如何使用 ReactiveSecurityContexHolder 进行 WebFluxTest

How to WebFluxTest whit ReactiveSecurityContexHolder

这里是一个简单的 Class 从 spring 安全上下文中读取主要用户:

public Mono<Void> getAndCheckAccessRights(Integer agencyKey) {
    return ReactiveSecurityContextHolder.getContext()
            .map(securityContext -> getAccessRights(agencyKey, securityContext.getAuthentication().getName()))
            .switchIfEmpty(Mono.defer(() -> {
                log.error("No security context found!");
                throw new AuthorizationException("No security context found!");
            }))
            .flatMap(accessRightsDtoMono -> checkAccessRights(accessRightsDtoMono))
            .then();
}

private Mono<AccessRightsDto> getAccessRights(Integer agencyKey, String bensl) {
    return dataServiceWebClient.get()
            .uri("/access_rights/" + agencyKey + "/" + bensl)
            .retrieve()
            .bodyToMono(AccessRightsDto.class)
            .switchIfEmpty(Mono.defer(() -> {
                log.error("No user found!");
                throw new AuthorizationException("No user found!");
            }));
}

虽然测试它不是它应该做的,但执行只是跳过代码行而不执行.map或.flatMap中的方法流, 没有打印日志,也没有任何级别的调试日志记录,测试只是在正确终止时运行,我不知道为什么会发生这种情况:

@WebFluxTest(AccessRightService.class)
...
@Test
@WithMockUser
void getAndCheckAccessRights_NOT_AUTHORIZED() throws JsonProcessingException {
    AccessRightsDto testAccessRightsDto = AccessRightsDto
            .builder(123456789, "test", "test", PUBLISH, PUBLISH, PUBLISH, PUBLISH, PUBLISH,
                    PUBLISH, PUBLISH, PUBLISH, NO_ACCESS)
            .build();
    MockResponse response = new MockResponse();
    response.setResponseCode(HttpStatus.OK.value()).setBody(objectMapper.writeValueAsString(testAccessRightsDto));
    mockWebServer.enqueue(response);
    assertThrows(AuthorizationException.class, () -> accessRightService.getAndCheckAccessRights(123456789));
}

当 运行 应用程序按预期正常运行时,测试很奇怪!

A​​pp 运行 spring 启动 2.2.2 和 okhttp3 mockwebserver。

不好意思,我忘了在 getAndCheckAccessRights 之后放置 .block() 来传播获取对象的输入,否则什么也不会发生。

实际上并不清楚它在 Netty 的情况下是如何工作的,因为它不接受 .block() 但在测试中可以调用它。