Java 安卓单元测试与改造和Mockito
我将改型api调用方法与活动代码分离,并希望对这些方法进行单元测试,例如: 界面:Java 安卓单元测试与改造和Mockito,java,android,unit-testing,mockito,retrofit,Java,Android,Unit Testing,Mockito,Retrofit,我将改型api调用方法与活动代码分离,并希望对这些方法进行单元测试,例如: 界面: public interface LoginService { @GET("/auth") public void basicLogin(Callback<AuthObject> response); } 公共接口登录服务{ @获取(“/auth”) 公共无效basicLogin(回调) 有人帮我:(问题是您在错误的时刻调用了verify:verify的目的是验证与mockApi的交
public interface LoginService {
@GET("/auth")
public void basicLogin(Callback<AuthObject> response);
}
公共接口登录服务{
@获取(“/auth”)
公共无效basicLogin(回调)
有人帮我:(问题是您在错误的时刻调用了verify
:verify
的目的是验证与mockApi的交互是否符合您的预期。因此通常您会看到如下内容:
authApi.login();
Mockito.verify(mockApi).basicLogin((cb.capture()));
这也是错误消息告诉您的:verify
预期调用basicLogin
,但实际不是
我也读过那篇文章,觉得缺少了一些东西。我实际上还不了解参数捕获。因此,我无法帮助您:)这篇文章不太清楚,因为它遗漏了安装步骤。通过访问文章中的链接,您可以看到完整的源代码,其中解释了缺少的步骤:
1) 代码示例是从测试特定活动的测试类中提取的。作为设置的一部分(即在@Before
中),它将活动对GitHub API实现的引用替换为模拟引用。然后调用活动的onCreate()
2) 在onCreate()
期间,活动调用现在被替换的GitHub API,并传入其回调
对象
前两个步骤解释了为什么每个测试开始时的Mockito.verify(mockApi).repositories(Mockito.anyString(),cb.capture());
步骤有效。由于测试在@之前运行,mockApi确实调用了它的repositories()
方法
代码的其余部分一旦就位就更容易理解。由于他只创建了一个mockApi
,但没有更改实际使用的回调
,因此活动的内容会发生更改。然后,代码的其余部分会通过检查列表视图或祝酒来验证这些更改是否已经发生
因此,要回答您的问题,您需要:
1) 在测试方法开始时,用mockApi对象替换AuthAPI的loginService对象,然后调用AuthAPI.Login()
2) 使用verify()
检查函数是否已被调用
3) 创建一个示例AuthObject
,并将其传递给cb.getValue().success()
函数
4) 从总线
获取AuthObject
,并断言它与发送到回调.success()函数的对象相同
这将测试您的AuthAPI.Login()
是否正确地将它将从改装中检索的AuthObject发送到您的Bus
(我意识到这个问题是很久以前写的,但最近我看到了同一篇文章,也有同样的困惑,我认为这个答案可能对其他人有用。)问题在于,您正在关注一个已有两年多历史的博客。此外,该作者两年没有更新他的代码,对此也没有兴趣。似乎您希望使用Android活动上下文来测试您的测试。我认为这不是测试REST API的最纯粹的方法,应该在JVM(junit)上进行测试@IgorGanapolsky如果你使用任何引用Android SDK的类,你就不能在JUnit中直接测试Android应用程序中的REST API,因为JUnit不会加载Android类。然而,这就是上面文章的目的——如何使用Robolectric和Mockito在不进行实际服务器调用的情况下执行REST API的本地测试,同时仍然可以访问缺少真正的Android类。@SteveHaley上面这篇文章的问题是它已经有两年了。这在Android开发的意义上是古老的。这段代码现在很难使用。@IgorGanapolsky我把它看作是一个例子/概念证明,而不是“这是正确的做事方式”。如果您有更新内容的链接,请随时发布。@IgorGanapolsky无法编译他的代码,这与Mockito与Robolectric是否是测试改型API的良好系统完全不同。这可以追溯到他的文章非常不清楚的地方。通过一些工作来填补空白,您可以创建工作测试使用他描述的系统。至于Mockito+Robolectric是否仍然是最好的方法,我不能说,因为我对替代方案不够熟悉。
@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.
authApi.login();
Mockito.verify(mockApi).basicLogin((cb.capture()));