spring-webfluxspring-testspring-restdocs

Spring webflux testing


I have a Spring webflux application with the service below.

@Configuration
public class RouterConfiguration {

    @Autowired
    private RegistrationHandler regHandler;

    @Bean
    public RouterFunction<ServerResponse> regRoute() {
        return RouterFunctions.route(POST(REGISTER_PATH).and(accept(APPLICATION_JSON)), regHandler::register);
    }
}

public Mono<ServerResponse> register(ServerRequest request) {
        return request.bodyToMono(Register.class).flatMap(reg -> {
            return buildOrg(reg).flatMap(orgRepository::save).flatMap(org -> 
                         ServerResponse.created(URI.create(USER_RESOURCE_URI + p.getUserId())).build());
        });
    }

I would like to test the above API and my test example,

@ExtendWith({ SpringExtension.class, RestDocumentationExtension.class })
@WebFluxTest({ RegistrationHandler.class })
@AutoConfigureWebTestClient(timeout = "100000")
class RegistrationHandlerTest {

    @Autowired
    ApplicationContext context;

    @MockBean
    PasswordEncoder passwordEncoder;

    @MockBean
    private OrgRepository orgRepository;

    @MockBean
    private UserRepository usrRepository;

    @Captor
    private ArgumentCaptor<Organization> orgInputCaptor;

    @Captor
    private ArgumentCaptor<Mono<Organization>> orgMonoInputCaptor;

    @Captor
    private ArgumentCaptor<User> usrInputCaptor;

    private WebTestClient webTestClient;

    @BeforeEach
    void setUp(RestDocumentationContextProvider restDocumentation) {
        webTestClient = WebTestClient.bindToApplicationContext(context).configureClient()
                .filter(documentationConfiguration(restDocumentation)).responseTimeout(Duration.ofMillis(100000))
                .build();
    }

    @Test
    @WithMockUser(username = "admin", roles = { "USER", "ADMIN" })
    public void testRegister() {

        final Register register = new Register();
        register.setOrgName("testOrg");
        register.setUsername("testUser");
        register.setPassword("testPwd");
        register.setCountry(1);

        final Organization org = new Organization();
        final User usr = new User();

        given(orgRepository.save(orgInputCaptor.capture())).willReturn(Mono.just(org));
        given(usrRepository.save(usrInputCaptor.capture())).willReturn(Mono.just(usr));

        webTestClient.mutateWith(csrf()).post().uri(REGISTER_PATH).contentType(APPLICATION_JSON).bodyValue(register)
                .exchange().expectStatus().is2xxSuccessful().expectBody();

        StepVerifier.create(orgMonoInputCaptor.getValue()).expectNext(org).expectComplete();

        then(usrRepository).should().save(usrInputCaptor.capture());

    }

}

The test case is failing for 404 NOT_FOUND error.

2021-02-02 08:06:37.488  INFO [AdminService,,] 28571 --- [    Test worker] s.a.s.h.RegistrationRequestHandlerTest : Starting RegistrationHandlerTest using Java 15.0.2 on 
    2021-02-02 08:06:37.489  INFO [AdminService,,] 28571 --- [    Test worker] s.a.s.h.RegistrationHandlerTest : No active profile set, falling back to default profiles: default
    2021-02-02 08:06:38.218  INFO [AdminService,,] 28571 --- [    Test worker] c.test.service.admin.AdminApplication   : Starting up Admin Application
    2021-02-02 08:06:38.458  INFO [AdminService,,] 28571 --- [    Test worker] ctiveUserDetailsServiceAutoConfiguration : 

    Using generated security password: fcd6963d-cf13-4eb8-a705-d46755493538

    2021-02-02 08:06:38.861  INFO [AdminService,,] 28571 --- [    Test worker] s.a.s.h.RegistrationRequestHandlerTest : Started RegistrationHandlerTest in 1.951 seconds (JVM running for 3.765)

RegistrationHandlerTest > testRegister() STANDARD_OUT
    2021-02-02 08:06:39.188 ERROR [AdminService,,] 28571 --- [    Test worker] o.s.t.w.reactive.server.ExchangeResult   : Request details for assertion failure:

    > POST http://localhost:8080/register
    > WebTestClient-Request-Id: [1]
    > Content-Type: [application/json]
    > Content-Length: [89]

    {"orgName":"testOrg","username":"testUser","password":"testPwd","country":1,"state":null}

    < 404 NOT_FOUND Not Found
    < Content-Type: [application/json]
    < Content-Length: [135]
    < Cache-Control: [no-cache, no-store, max-age=0, must-revalidate]
    < Pragma: [no-cache]
    < Expires: [0]
    < X-Content-Type-Options: [nosniff]
    < X-Frame-Options: [DENY]
    < X-XSS-Protection: [1 ; mode=block]
    < Referrer-Policy: [no-referrer]

    {"timestamp":"2021-02-02T16:06:39.150+00:00","path":"/register","status":404,"error":"Not Found","message":null,"requestId":"21d38b1c"}


Gradle Test Executor 13 finished executing tests.

> Task :test-admin:test FAILED

RegistrationRequestHandlerTest > testRegister() FAILED
    java.lang.AssertionError: Range for response status value 404 NOT_FOUND expected:<SUCCESSFUL> but was:<CLIENT_ERROR>
        at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
        at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
        at org.springframework.test.web.reactive.server.StatusAssertions.lambda$assertSeriesAndReturn$5(StatusAssertions.java:235)
        at org.springframework.test.web.reactive.server.ExchangeResult.assertWithDiagnostics(ExchangeResult.java:227)
        at org.springframework.test.web.reactive.server.StatusAssertions.assertSeriesAndReturn(StatusAssertions.java:233)
        at org.springframework.test.web.reactive.server.StatusAssertions.is2xxSuccessful(StatusAssertions.java:177)
        at com.test.service.admin.spring.handler.RegistrationHandlerTest.testRegister(RegistrationHandlerTest.java:90)

1 test completed, 1 failed

Am I missing anything?


Solution

  • I missed the RouterConfiguration class in the WebFluxTest annotation and it's working fine after adding the same.

    @WebFluxTest({ RegistrationHandler.class, RouterConfiguration.class })