Reputation: 1
i am new to reactive Programming with Java and somehow i am missing a point in writing a test for my Reactive WebClient.
I am using The following reactive WebClientConfig
@Configuration
public class DynamicsWebClientConfig {
@Bean
WebClient dynamicsClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth2Client.setDefaultClientRegistrationId("dynamics");
return WebClient.builder()
.filter(oauth2Client)
.build();
}
}
Using that Client within an Controller within an "normal application run" will always work correctly doing the Oauth2 when neccecary and then reqeusting the Data, so i thought lets write a test for that so i am sure this always works. Thats why i ended up with the following TestClass
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(locations = "classpath:application-test.properties")
public class DynamicsClientTest {
@Autowired
private WebClient dynamicsClient;
@Test
public void testDynamicsClient() {
String responseBody = dynamicsClient.get()
.uri("https://api.businesscentral.dynamics.com/<some_ids_an_context_here>/customers")
.retrieve()
.bodyToMono(String.class)
.block();
assertNotNull(responseBody);
assertEquals("expectedData", responseBody);
}
}
Running the TEST will result in the Error serverWebExchange cannot be null at org.springframework.security.oauth2.client.web.DefaultReactiveOAuth2AuthorizedClientManager.lambda$authorize$4
I thought when using @SpringBootTest the full apllication Context is loaded and i can do test as i would use the application. Yet this Error suggests that my reactive Application Test is not loaded Properly. Am i missing something is reactiveApplications handled differently?
I found out that i could use WebFluxTest but this would not load the application context properly therefor the configuration classes will not be loaded and i am still not able to do an oauth2 reactive webclient request.
I also tried:
Somehow my Test seams to be using "DefaultReactiveOAuth2AuthorizedClientManager" which is generating the Error. But running the Application "normaly" there seams to be used a different Manager which will not result in the same Error.
Any help with writing my supposed to be Easy Test?
Upvotes: -1
Views: 75
Reputation: 1
I did find the solution anticipating a similar not reactive related but oauth related Solution here `servletRequest cannot be null` -> SpringBoot - WebClient - GET request with Keycloak
To the WebClient config needs to be added an AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager as follows
@Configuration
public class DynamicsWebClientConfig {
@Bean
WebClient dynamicsClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2Client =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth2Client.setDefaultClientRegistrationId("dynamics");
return WebClient.builder()
.filter(oauth2Client)
.build();
}
@Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
ReactiveClientRegistrationRepository clientRegistrationRepository,
ReactiveOAuth2AuthorizedClientService clientService) {
// Configure the authorized client provider with refresh token and client credentials
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.refreshToken()
.clientCredentials()
.build();
// Instantiate the AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository, clientService);
// Set the authorized client provider
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
}
`
You are able to test the ReactiveEndPoint as follows:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT )
public class DynamicsClientTest {
@Autowired
private WebClient dynamicsClient;
@Test
public void testDynamicsClient() {
// Use the dynamicsClient to make a request
String responseBody = dynamicsClient.get()
.uri(<some_api_endpint_here>/customers)
.retrieve()
.bodyToMono(String.class)
.block();
// Validate that the response is not null and matches the expected result
assertNotNull(responseBody);
// You might want to validate the response further, depending on your requirements
// For example: assertEquals("expectedData", responseBody);
}
}
Upvotes: 0