使用Mockito模拟部分模拟的连续响应的通用数量

时间:2012-03-28 16:00:31

标签: mockito

我正在创建一个用于测试HTTP交互的通用模拟客户端。为此,我希望能够对同一方法做出一些回应。 使用普通的模拟,这不会是一个问题:

when(mock.execute(any(), any(), any())).thenReturn(firstResponse, otherResponses)

但是,我使用的是部分模拟,我只是想模拟发出HTTP请求的方法,因为在单元的上下文中可能无法访问实时端点或Internet - 执行测试。

所以我将做类似的事情:

doReturn(response).when(spy).execute(hostCaptor.capture(), requestCaptor.capture(), contextCaptor.capture());

但是,我希望能够支持多个响应(不是很多“交互”)。但是没有doReturn方法,它一次只能获得一个响应。

我对解决方案的第一次尝试是迭代地进行:

Stubber stubber = null;
for (HttpResponse response : responses) {
    if (stubber == null) {
        stubber = doReturn(response);
    } else {
        stubber = stubber.doReturn(response);
    }
}
stubber.when(spy).execute(hostCaptor.capture(), requestCaptor.capture(), contextCaptor.capture());

但是在运行测试时无法验证(检测到“未完成的存根”)。

所以 - 有没有办法用Mockito来实现这个目标?

感谢阅读。

2 个答案:

答案 0 :(得分:3)

你可以写

doReturn( 1 ).doReturn( 2 ).doReturn( 3 ).when( myMock ).myMethod( any(), any(), any());

修改

如果您想要的值在数组myArray中,那么您也可以使用

import static java.util.Arrays.asList;
import static org.mockito.Mockito.doAnswer;
import org.mockito.stubbing.answers.ReturnElementsOf

....

doAnswer( new ReturnsElementsOf( asList( myArray )))
   .when( myMock ).myMethod( any(), any(), any());

答案 1 :(得分:1)

我找到的解决方案是使用doAnswer返回数组中的下一个响应。

Answer<HttpResponse> answer = new Answer<HttpResponse>() {

    HttpResponse[] answers = responses;
    int number = 0;

    @Override
    public HttpResponse answer(InvocationOnMock invocation) throws Throwable {
        HttpResponse result = null;
        if (number <= answers.length) {
            result = answers[number]; 
            number++;
        } else {
            throw new IllegalStateException("No more answers");
        }
        return result;
    }
};
doAnswer(answer).when(spy).execute(hostCaptor.capture(), requestCaptor.capture(), contextCaptor.capture());