在junit测试中,反应器switchifempty的行为不像预期的那样

我正在为下面提供的方法编写测试。 `

class ScrapedRecipeCache @Autowired constructor(private val cache: RecipeScrapingCacheService, private val recipeService: RecipeService) : ScrapedRecipeProvider { override fun provide(request: ScrapingRequest): Flux<ScrapedRecipe> = cache.retrieve(request.link) .doOnNext { println(it) } .flatMap { (link, _, recipeHash, error) -> recipeService.findByHash(recipeHash) .map { ScrapedRecipe(it, link, error)} .switchIfEmpty(cache.remove(request.link).then(Mono.empty())) } .flux() } 

`测试看起来如下:

 private val recipeFetched = Recipe("Tortellini", RecipeDifficulty.EASY, 15.0) val cacheContents = RecipeScrapingResource("www.google.com", ScrapingOrigin.JAMIE_OLIVER, recipeFetched.hash, mutableListOf( pl.goolash.core.Exception("aa", ErrorType.WARNING, LocalDateTime.MIN) )) val request = ScrapingRequest("www.google.com", ScrapingOrigin.JAMIE_OLIVER, 4) @BeforeEach fun setUp() { given(cache.retrieve("www.google.com")).willReturn(Mono.just(cacheContents)) given(recipeService.findByHash(recipeFetched.hash)).willReturn(Mono.just(recipeFetched)) } @Test @DisplayName("Then return data fetched from service and don't delete cache") fun test() { cacheFacade.provide(request) .test() .expectNext(ScrapedRecipe(recipeFetched, "www.google.com", cacheContents.error!!)) .expectComplete() .verify() BDDMockito.verify(cache, BDDMockito.never()).remove(request.link) } 

测试失败,因为cache.remove(request.link)被调用。 我的理解(或从我从文档中收集的)switchIfEmpty,应该只在recipeService.findByHash返回Mono.empty()时被触发。 但是调试器显示它返回Mono.just(fetchedRecipe)的模拟值。

有趣的是,当我更换

 .switchIfEmpty(cache.remove(request.link).then(Mono.empty())) 

 .switchIfEmpty(Mono.just(1).doOnNext{println("weeee")}.then(Mono.empty())) 

然后,weee不会被打印,因此它的行为如预期的那样,即switchIfEmpty没有被触发。

此外,测试的问题在集成测试中正常运行,并不清除缓存。

反应堆版本:3.1.0-RC1其他值得注意的细节:Spring Boot 2.0.0-M4,Mockito-core:2.10,junit 5,项目用kotlin编写

问题是,有没有人看到这个问题? 因为我已经花了两天的时间,而且还不知道为什么这个表现如此b </s>。

最后,我发现如何使这项工作。

为了补救它:

  override fun provide(request: ScrapingRequest): Flux<ScrapedRecipe> = cache.retrieve(request.link) .flatMap { (link, _, recipeHash, error) -> recipeService.findByHash(recipeHash) .map { ScrapedRecipe(it, link, error) } .switchIfEmpty(Mono.just(1) .flatMap { cache.remove(request.link) } .then(Mono.empty())) } .flux() 

你可以看到如何使用flatMap执行异步工作来完成这个工作,即使这不是最好的实现,它向我揭示了一个相当有趣的机制。