Reactor switchifempty 在 junit 测试中的行为不符合预期
Reactor switchifempty does not behave as expected in junit test
我正在为下面提供的方法编写测试。
`
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 returns Mono.empty() 时触发。然而,调试器显示它 returns 模拟了 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 编写的
问题是,有人认为这有什么问题吗?因为我已经花了两天时间,仍然不知道为什么会出现如此奇怪的情况。
我终于找到了如何让它工作。
为了补救:
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 来执行异步工作,即使这不是最简洁的实现,它向我揭示了隐藏在这里的一个非常有趣的机制。
我正在为下面提供的方法编写测试。 `
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 returns Mono.empty() 时触发。然而,调试器显示它 returns 模拟了 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 编写的
问题是,有人认为这有什么问题吗?因为我已经花了两天时间,仍然不知道为什么会出现如此奇怪的情况。
我终于找到了如何让它工作。
为了补救:
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 来执行异步工作,即使这不是最简洁的实现,它向我揭示了隐藏在这里的一个非常有趣的机制。