【问题标题】:Reactor switchifempty does not behave as expected in junit testReactor switchifempty 在 junit 测试中的行为不符合预期
【发布时间】:2018-03-19 17:50:30
【问题描述】:

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

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 编写的

问题是,有人认为这有什么问题吗?因为我已经花了两天时间,仍然不知道为什么它的行为如此奇怪。

【问题讨论】:

    标签: spring-boot mockito kotlin project-reactor


    【解决方案1】:

    我终于找到了如何完成这项工作。

    为了补救它:

     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 执行异步工作是如何完成这项工作的,即使这不是最简洁的实现,它也向我揭示了隐藏在这里的一个非常有趣的机制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-18
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 2022-01-06
      • 1970-01-01
      相关资源
      最近更新 更多