Spring webflux 测试

如何解决Spring webflux 测试

我有一个带有以下服务的 Spring webflux 应用程序。

@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());
        });
    }

我想测试上面的 API 和我的测试示例,

@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());

    }

}

测试用例因 404 NOT_FOUND 错误而失败。

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

我错过了什么吗?

解决方法

@WebFluxTest 用于测试使用 WebFlux 基于注解的编程模型的应用程序的切片。它包括 @Controller 豆(以及其他)但不包括 RouterFunction 豆。 value@WebFluxTest 属性应用于标识您要测试的特定 @Controller,而不是测试所有 @Controller bean。 @WebFluxTest({ RegistrationHandler.class }) 看起来不对,因为我认为 RegistrationHandler 不是控制器。

您应该改用 @SpringBootTest@Import RouterFunction 实现,如 Spring Boot reference documentation 中所述:

@WebFluxTest 无法检测通过功能性 Web 框架注册的路由。要在上下文中测试 RouterFunction bean,请考虑通过 RouterFunction 或使用 @Import 自己导入您的 @SpringBootTest

,

我错过了 WebFluxTest 注释中的 RouterConfiguration 类,添加相同后它工作正常。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?