我正在尝试使用 Mockito 对我的 API 的调用进行单元测试。我查看了S.O上已经提到的所有问题以及解决方案,但到目前为止,它们都不是决定性的。
MyService是一个包含多个资源的接口。下面是一个示例:
public interface MyService {
@GET("/myresource")
Call<MyResponse> getDataFromServer();
}
在我的应用程序类中,我有一个静态类,它返回 MyService 的实例
public static MyService getApiService() {
return mApiService;
}
因此,从那里开始,在我的一个类中,我调用 Web 服务:
Call<MyResponse> call = getApiService.getDataFromServer();
call.enqueue(myCallback)
其余的跟随调用回调方法....
这是我的测试类:
@RunWith(AndroidJUnit4.class)
public class SampleTest {
@Mock
private MyService mService;
@Captor
private ArgumentCaptor<Callback<MyResponse>> callbackArgumentCaptor;
@Mock
private Call<MyResponse> mockCall;
// Rule to trigger the creation of @Mock annotated objects.
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Test
public void testDoAction() throws NullInsteadOfMockException {
when(mService.doSomeAction()).thenReturn(mockCall);
mService.doSomeAction();
verify(mockCall).enqueue(callbackArgumentCaptor.capture());
}
}
这是我运行测试后遇到的错误:
Wanted but not invoked:
mockCall.enqueue(
<Capturing argument>
);
Actually, there were zero interactions with this mock.
即使使用MockitoJunitRunner(代替AndroidJunitRunner(并在我定义如下的设置方法中初始化我的模拟对象,我也有同样的错误:
@Before
public void setUp() throws Exception{
MockitoAnnotations.initMocks(this);
}
莫米托版本 : 2.7.19
我希望能够测试 API 响应,所以我模拟了 API 服务,为改造回调定义了一个捕获器
你在这里想做的事情有点奇怪。你正在测试一个类,但你嘲笑它。您应该测试真正的类 - MyService
.我假设您的服务看起来有点像:
public class MyService {
private final Call<MyResponse> call;
public MyService(Call<MyResponse> call) {
this.call = call;
}
public void doSomeAction() {
call.enqueue(...);
}
}
理想情况下,您应该具有以下内容:
@RunWith(AndroidJUnit4.class)
public class SampleTest {
private MyService mService;
@Captor
private ArgumentCaptor<Callback<MyResponse>> callbackArgumentCaptor;
@Mock
private Call<MyResponse> mockCall;
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Before
public void setUp() throws Exception{
MockitoAnnotations.initMocks(this);
mService = new MyService(mockCall);
}
@Test
public void testDoAction() throws NullInsteadOfMockException {
mService.doSomeAction();
verify(mockCall).enqueue(callbackArgumentCaptor.capture());
}
}
所以这个想法是模拟你正在单元测试的类的所有依赖项,并以某种方式将它们传递给类。在这里,我将它们注入到构造函数中。我不知道你是否是这种情况,但二传手或田野也有效。
然后,测试只是调用服务类中的实际方法,如果此方法假定将调用排队,则验证应该通过。
它在您的情况下不起作用的原因是因为您正在嘲笑该服务,因此当您调用mService.doSomeAction()
时,这不会调用您的实现,我想应该调用enqueue
。这就是验证失败的原因。换句话说,确实从未在调用对象上调用enqueue
。