我从活动代码中分离了改进的api调用方法,我想对这些方法进行单元测试,例如: 界面:
public interface LoginService {
@GET("/auth")
public void basicLogin(Callback<AuthObject> response);
}
这是执行调用的方法,在主活动中我通过事件总线获取对象。
public class AuthAPI {
private Bus bus;
LoginService loginService;
public AuthAPI(String username, String password) {
this.bus = BusProvider.getInstance().getBus();
loginService = ServiceGenerator.createService(LoginService.class,
CommonUtils.BASE_URL,
username,
password);
}
public void Login() {
loginService.basicLogin(new Callback<AuthObject>() {
@Override
public void success(AuthObject authObject, Response response) {
bus.post(authObject);
}
@Override
public void failure(RetrofitError error) {
AuthObject authObject = new AuthObject();
authObject.setError(true);
bus.post(authObject);
}
});
}
}
这里是测试
@RunWith(MockitoJUnitRunner.class)
public class AuthCallTest extends TestCase {
AuthAPI authAPI;
@Mock
private LoginService mockApi;
@Captor
private ArgumentCaptor<Callback<AuthObject>> cb;
@Before
public void setUp() throws Exception {
authAPI = new AuthAPI("username", "password");
MockitoAnnotations.initMocks(this);
}
@Test
public void testLogin() throws Exception {
Mockito.verify(mockApi).basicLogin((cb.capture()));
AuthObject authObject = new AuthObject();
cb.getValue().success(authObject, null);
assertEquals(authObject.isError(), false);
}
}
当我启动测试时出现此错误
Wanted but not invoked:
mockApi.basicLogin(<Capturing argument>);
-> at AuthCallTest.testLogin(AuthCallTest.java:42)
Actually, there were zero interactions with this mock.
我做错了什么,这让我发疯了 我试图遵循本指南但没有成功: http://www.mdswanson.com/blog/2013/12/16/reliable-android-http-testing-with-retrofit-and-mockito.html
有人帮助我:(答案 0 :(得分:21)
文章不太清楚,因为它错过了设置步骤。通过访问文章中链接的GitHub project,您可以看到解释这些缺失步骤的完整源代码:
1)从测试特定活动的测试类中提取代码示例。作为设置的一部分(即在@Before
中),它用模拟的一个替换了Activity对GitHub API实现的引用。然后它调用活动的onCreate()
。
2)在onCreate()
期间,活动调用现在替换的GitHub API,并传入其Callback
对象。
前两个步骤解释了每个测试开始时Mockito.verify(mockApi).repositories(Mockito.anyString(), cb.capture());
步的原因。当测试在@Before
之后运行时,mockApi确实对其repositories()
方法进行了调用。
其他代码一旦到位就更容易理解。由于他仅创建了mockApi
,但未更改正在使用的实际Callback
,因此活动的内容已更改。然后,其余代码通过检查ListView或Toasts来验证是否已发生这些更改。
所以要回答你的问题,你需要:
1)在测试方法开始时,用mockApi对象替换AuthAPI的loginService对象,然后调用AuthAPI.Login()
。
2)使用verify()
检查是否已调用该函数。
3)创建示例AuthObject
并将其传递给cb.getValue().success()
函数。
4)从AuthObject
获取Bus
,并断言它与您发送到callback.success()
函数的内容相同。
这会测试您的AuthAPI.Login()
是否正确地向Bus
发送了它将从Retrofit中检索到的AuthObject
。
(我意识到SO问题是在不久前写的,但是当我遇到同一篇文章并且最近也有同样的困惑时,我认为这个答案可能对其他人有用。) < / p>