我有一个像这样的简单存储库实现。

@Repository
public interface PolicyRepository extends ReactiveMongoRepository<Policy, String> {

    @Query("{ id: { $exists: true }}")
    Flux<Policy> findAllPaged(Pageable pageable);
    @Query("{ name: { $eq: ?0 }}")
    Mono<Policy> findByName(String name);
}


在这样的控制器上有一个简单的动作方法。

    @ResponseStatus(HttpStatus.CREATED)
    public Mono<ResponseEntity<String>> createPolicy(@Valid @RequestBody Policy policy) {
        //Use The Mongodb ID Generator
        policy.setId(ObjectId.get().toString());
        return policyRepository.findByName(policy.getName()).flatMap(policy1 -> {
            return Mono.just(ResponseEntity.badRequest().body("A Policy with the same name as the policy you are trying to create" +
                    "already exists"));
  }).switchIfEmpty(
          policyRepository.save(policy).map(p2 ->{
                    eventPublisher.publish(Events.POLICY_CREATED, p2.getId());
            return ResponseEntity.status(HttpStatus.CREATED).body("Policy definition created successfully");
                }));
    }


我要实现的目标是,如果存在与插入的策略同名的策略,则返回错误请求;如果findByName方法返回空,则执行保存操作。

奇怪的行为是,以下测试失败,因为无论findByName是否返回数据,总是会调用save。

这是测试

@Test
    void testCreateDuplicatePolicyShouldFail() {
        given(policyRepository.findByName(eq(policy.getName()))).willReturn(Mono.just(policy));
        given(policyRepository.save(any(Policy.class))).willReturn(Mono.just(policy));
        given(eventPublisher.publish(Events.POLICY_CREATED, policy.getId())).willReturn(Mono.just(0L));
        webTestClient.post().uri("/policies")
                .syncBody(policy)
                .exchange()
                .expectStatus().isBadRequest();
        verify(policyRepository, times(1)).findByName(eq(policy.getName()));
        verify(policyRepository, times(0)).save(any(Policy.class));
        verify(eventPublisher, times(0)).publish(Events.POLICY_CREATED, policy.getId());
    }


它失败,并带有以下异常

org.mockito.exceptions.verification.NeverWantedButInvoked:
com.management.dashboard.repository.PolicyRepository#0 bean.save(
    <any com.management.core.model.Policy>
);


请我做错什么了。任何指针将不胜感激。

最佳答案

您能否确认在测试中您正在设置一个空的单声道。

您能否替换下面的行:

given(policyRepository.findByName(eq(policy.getName()))).willReturn(Mono.just(policy));


用这一行:

given(policyRepository.findByName(eq(policy.getName()))).willReturn(Mono.empty());


仅当流为空时才调用switchIfEmpty运算符。
此外,您还可以启用日志来跟踪流。这可以通过在switchIfEmpty之后添加一个日志运算符来完成。例如

 return policyRepository.findByName()
                        .switchIfEmpty()
                        .log();

10-05 18:45