Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking OAuth2 client with WebTestClient for servlet applications results in null httpHandlerBuilder

My Spring Boot application acts as an OAuth2 client by using the spring-boot-starter-oauth2-client dependency.

Now I'd like to write an integration test (@SpringBootTest) to verify the behavior of a REST endpoint secured by OAuth2. The Testing OAuth 2.0 Clients documentation describes that it is possible to use mutateWith(mockOAuth2Client()) to mock a login via OAuth2.

public class UserIT {

  @Autowired
  private WebTestClient webTestClient;

  @Test
  void test() {
    webTestClient
      .mutateWith(mockOAuth2Client("keycloak"))
      .get()
      .uri("/api/user/1345")
      .exchange()
      .expectStatus().isOk();
  }
}

However, the test fails with the following message:

java.lang.NullPointerException: Cannot invoke "org.springframework.web.server.adapter.WebHttpHandlerBuilder.filters(java.util.function.Consumer)" because "httpHandlerBuilder" is null
    at org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers$OAuth2ClientMutator.afterConfigurerAdded(SecurityMockServerConfigurers.java:1113)
    at org.springframework.test.web.reactive.server.DefaultWebTestClientBuilder.apply(DefaultWebTestClientBuilder.java:265)
    at org.springframework.test.web.reactive.server.DefaultWebTestClient.mutateWith(DefaultWebTestClient.java:167)

As far as I have understood it, this WebTestClient setup is only suitable for "Reactive Applications" whereas my application is a "Servlet Application". Unfortunately, I cannot find the necessary information how to mock this OAuth2 client for a servlet application.

like image 925
Robert Strauch Avatar asked Sep 16 '25 11:09

Robert Strauch


1 Answers

I was able to run your exact @Autowired and @Test code successfully with the following test configuration:

@Configuration
@ComponentScan
public class TestConfig {

    @Bean
    public WebTestClient webTestClient(ApplicationContext applicationContext) {
        return WebTestClient.bindToApplicationContext(applicationContext).build();
    }

    @Bean
    public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange().anyExchange().permitAll();
        return http.build();
    }
}
like image 126
Zack Macomber Avatar answered Sep 19 '25 07:09

Zack Macomber