代码之家  ›  专栏  ›  技术社区  ›  rafaelasguerra

如何测试RxJava Map/Flapmap中的模拟交互

  •  1
  • rafaelasguerra  · 技术社区  · 6 年前

    我正试着用mockito测试这段代码。

    public class Repository {
    ...
        @Override
        public Observable<Data> getCurrentData() {
            return api.getData()
                    .map(entityMapper::transform);
        }
    }
    

    我想测试entitymapper交互。这里是我的测试场景:

    @Test
    @Throws(Exception::class)
    fun getData() {
        //given
        whenever(api.getData).thenReturn(Observable.just(Data()))
        //when
        debitCardRepo.getCurrentData
        //then
        verify(api).getData
        //TODO verify entityMapper interaction 
    }
    

    如果我试着 verify(entityMapper).transform(anyOrNull<>()) ,我会得到 Wanted but not invoked: 有人知道如何在map/flapmap中测试模拟交互吗?

    2 回复  |  直到 6 年前
        1
  •  2
  •   David Rawson B Aristide    6 年前

    有人知道如何在map/flapmap中测试模拟交互吗?

    假设你班上的其他同学都是这样的:

    public class Repository {
    
        private final EntityMapper
    
        public Repository(EntityMapper entityMapper) {
            this.entityMapper = entityMapper;
        }
    
        @Override
        public Observable<Data> getCurrentData() {
            return api.getData()
                    .map(entityMapper::transform);
        }
    }
    

    然后在一个被嘲笑的 EntityMapper 如果你等着 Observable 完成:

    @Test
    @Throws(Exception::class)
    fun testGetData() {
        //given
        val data = Data()
        whenever(api.getData).thenReturn(Observable.just(data))
        //when
        repository.getCurrentData().blockingGet()
        //then
        verify(entityMapper).transform(any())
    }
    

    注意呼叫 blockingGet() -否则,测试可能在映射发生之前完成。你也应该看看 Observable#test() 方法查看更好的选项。

    但是在这种情况下,由于存储库除了委派给api和调用 实体外观 这似乎是你感兴趣的主要互动,为什么不测试一下 实体外观 分开?

    如果你为 实体外观 然后可以使用黑盒测试(只需调用 transform 并查看转换是否符合您的期望)。这种测试比使用 verify 有时会退化为测试,这是被测系统的反向实现。

        2
  •  2
  •   Andrew G    6 年前

    你没有订阅。

    debitCardRepo.getCurrentData 只会返回一个 Observable 但实际上什么也没做。

    @Test
    @Throws(Exception::class)
    fun getData() {
        //given
        whenever(api.getData).thenReturn(Observable.just(Data()))
        //when
        debitCardRepo.getCurrentData.subscribe()
        //then
        verify(api).getData 
    }
    

    不管怎样,这不是一个很好的测试,因为你正在测试一个副作用的发生。调用了一些映射/转换函数。为什么不测试一下输出呢?

    @Test
    @Throws(Exception::class)
    fun getData() {
        //given
        val data = Data()
        whenever(api.getData).thenReturn(Observable.just(data))
        //when
        val transformedData = debitCardRepo.getCurrentData.blockingGet()
        //then
        assertEquals(data, transformedData)
    }
    

    这是一个更有意义的测试。简单的重构不会破坏这个测试,除非改变类的行为。