如何测试异步方法,而不是用Mockito模拟对象?

时间:2015-03-26 07:30:10

标签: java unit-testing mocking mockito

我想用Mockito

测试下面的代码
@Override
public void getSessionList(final int carId, final ResultCallback<List<Session>> callback) {
    jobExecutor.execute(new Runnable() {
        @Override
        public void run() {
            List<SessionEntity> sessions = IDataStore.getSessionList(carId);
            final List<Session> sessionList = new ArrayList<>();
            if (sessions != null) {
                for (SessionEntity entity : sessions) {
                    sessionList.add(mapper.transform(entity));
                }
                uiThread.post(new Runnable() {
                    @Override
                    public void run() {
                        if (callback != null) {
                            callback.onResult(sessionList);
                        }
                    }
                });
            } 
        }
    });
}

我尝试做类似的事情,但我的验证方法将比runnable早执行。 Thread.sleep()适用于前两个验证,但是如何测试将在主线程中执行的 callback.onResult 的结果?

private Repository repository // not mocked
@Mock
private IDataStore dataStore;
@Mock
private DataToDomainMapper dataToDomainMapper;
@Mock
private ResultCallback resultCallback;

@Test
public void testGetSessionListCallbackSuccess(){
    List<SessionEntity> sessionEntities = Arrays.asList(sessionEntity, sessionEntity, sessionEntity);

    given(dataStore.getSessionList(anyInt())).willReturn(sessionEntities);
    given(dataToDomainMapper.transform(any(SessionEntity.class))).willReturn(session);

    repository.getSessionList(1, resultCallback);

    verify(dataStore).getSessionList(anyInt());
    verify(dataToDomainMapper, times(3)).transform(any(SessionEntity.class));
    verify(resultCallback).onResult(any(List.class));
}

2 个答案:

答案 0 :(得分:1)

检查用于测试名为Awaitility的异步方法的工具。非常方便的工具,为测试异步方法节省了我很多时间。

答案 1 :(得分:0)

我相信你可以将匿名Runnable移动到内部(或嵌套)类并在两个部分上进行拆分测试:检查jobExecutor是否开始执行相应的类实例,并检查内部/嵌套类的run()方法是否按预期工作