gpt4 book ai didi

java - Reactor switchIfEmpty 并验证执行

转载 作者:行者123 更新时间:2023-12-02 10:46:53 28 4
gpt4 key购买 nike

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

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

以及像这样的 Controller 上的简单操作方法。

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

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

最佳答案

模拟设置的问题是总是调用save()。真实存储库返回的 Mono 是惰性的,因此在订阅它之前不会发生任何事情。 switchIfEmpty 的工作是仅当没有收到 onNext 信号时才进行所述订阅。

方法调用就是一个方法调用。 switchIfEmpty 无法阻止 save 以这种形式执行。就好像您有类似 System.out.println(getMessage()) 的东西:每当执行整行时都会调用 getMessage ;)

为了进行测试,您可以在模拟中使用reactor-testPublisherProbe:

@Test
void testCreateDuplicatePolicyShouldFail() {

//set up a probe to verify that the save Mono is never triggered
PublisherProbe probe = PublisherProbe.of(Mono.just(policy));
//now let the `save` return the probe:
given(policyRepository.save(any(Policy.class))).willReturn(probe.mono());

//rest of the mock and invocation is same
given(policyRepository.findByName(eq(policy.getName()))).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(eventPublisher, times(0)).publish(Events.POLICY_CREATED, policy.getId());

//but we now actually expect the save() to be invoked, but the probe to be inert:
verify(policyRepository, times(1)).save(any(Policy.class));
probe.assertWasNotSubscribed();

}

关于java - Reactor switchIfEmpty 并验证执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52475968/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com