我正在尝试使用Mockito对我的api进行单元测试。 我看一下S.O已经提到的所有问题以及解决方案,但到目前为止,它们都没有定论。
MyService是一个包含多个资源的接口。这是一个示例:
public interface MyService {
@GET("/myresource")
Call<MyResponse> getDataFromServer();
}
在我的Application类中,我有一个返回MyService实例的静态类
public static MyService getApiService() {
return mApiService;
}
所以,从我的一个班级里面,我打电话给网络服务:
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);
}
Mockito版本:2.7.19
我希望能够测试API响应,所以我嘲笑了API服务,为改装回调定义了一个捕获器
答案 0 :(得分:0)
你在这里尝试做什么有点奇怪。你正在测试一个类,但你嘲笑它。你应该测试真正的班级 - 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());
}
}
因此,我们的想法是模拟您进行单元测试的类的所有依赖关系,并以某种方式将它们传递给类。在这里,我将它们注入构造函数中。我不知道你是否属于这种情况,但是制定者或领域也是如此。
然后测试只是调用服务类中的real方法,如果这个方法假设要将调用入队,那么验证应该通过。
它在您的情况下不起作用的原因是因为您正在嘲笑该服务,所以当您致电mService.doSomeAction()
时,这并不会调用您的实施,我认为应该致电{\ n} {1}}。这就是验证失败的原因。换句话说,永远不会在调用对象上调用enqueue
。