Google在其官方文档Building Local Unit Tests中提到,如果你的单元测试没有作何依赖或者仅仅依赖于Android, 你就应该在本地机器上跑你的测试case, 不应该让程序跑在移动设备或者模拟器中,这样是最高效,这个时候你需要用到一个Mocking framework, 像Mockito。 之前我们有用到Robolectric,感觉也还不错,不过既然Google推荐用Mockito,便来尝试一下。
默认情况下,我们的测试代码会方在src/test/java下,这是官方给规定的。
添加 Mockito 在build.gradle文件中
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
// required if you want to use Mockito for unit tests
testCompile 'org.mockito:mockito-core:1.+'
// required if you want to use Mockito for Android instrumentation tests
// androidTestCompile 'org.mockito:mockito-core:1.+'
// androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
// androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
// androidTestCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1' //可删除
compile 'com.android.support:design:23.1.1' //可删除
}
@RunWith(MockitoJUnitRunner.class)
public class LoginPresenterTest {
@Mock
private LoginView view;
@Mock
private LoginService service;
private LoginPresenter presenter;
@Before
public void setUp() throws Exception {
presenter = new LoginPresenter(view, service);
}
@Test
public void showErrorMessageWhenUserNameIsEmpty() throws Exception {
when(view.getUserName()).thenReturn("");
presenter.onLoginClicked();
verify(view).showUserNameError(R.string.username_error);
}
@Test
public void showErrorMessageWhenPasswordIsEmpty() throws Exception {
when(view.getUserName()).thenReturn("James");
when(view.getPassword()).thenReturn("");
presenter.onLoginClicked();
verify(view).showPasswordError(R.string.password_error);
}
@Test
public void startActivity() throws Exception {
when(service.login("james", "bond")).thenReturn(true);
when(view.getUserName()).thenReturn("james");
when(view.getPassword()).thenReturn("bond");
presenter.onLoginClicked();
verify(view).startMainActivity();
}
}
执行Case
Google是这么说的:
To run local unit tests in your Gradle project from Android Studio:
1. In the Project window, right click on the project and synchronize your project.
2. Open the Build Variants window by clicking the left-hand tab, then change the test artifact to Unit Tests.
3. In the Project window, drill down to your unit test class or method, then right-click and run it.
Android Studio displays the results of the unit test execution in the Run window.
//You can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);
//stubbing
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());
//following prints "first"
System.out.println(mockedList.get(0));
//following throws runtime exception
System.out.println(mockedList.get(1));
//following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));
在此记录一下Android中如何采用JUnit和Macktio进行单元测试。 写代码总觉得有了测试心里面会更有底气一些,同时单元测试也会使我们的生产率大大提高。每完成一个功能就没有必要去拿到Android手机上去跑一下,这样太费时了。最近行业内对MVx模式炒得很热,昨晚在Youtube上看了个相关的视屏,采用MVP模式来架构一个App, 然后写单元测试很是方便,在此记录一下。代码是边看视屏边敲的,后来发现,其实作者已经将代码开源了。可以从这里找到。
关于Mockito
Google在其官方文档Building Local Unit Tests中提到,如果你的单元测试没有作何依赖或者仅仅依赖于Android, 你就应该在本地机器上跑你的测试case, 不应该让程序跑在移动设备或者模拟器中,这样是最高效,这个时候你需要用到一个Mocking framework, 像Mockito。 之前我们有用到Robolectric,感觉也还不错,不过既然Google推荐用Mockito,便来尝试一下。
默认情况下,我们的测试代码会方在src/test/java下,这是官方给规定的。
添加 Mockito 在build.gradle文件中
MVP
这篇文章里面讲得不错。个人觉得在Web的开发中,MVC是被大家所熟知,也很好理解。Model, View, Controller职责非常清楚。以普通的Java Web项目为例,通常会是一个JavaBean作为Model, 以JSP文件作为View, 以Servlet作为Controller,结构非常清晰。但在Android开发中,MVC架构是不能直接拿过来用的,主要因为Activity的角色不清晰,一方便要做为View, 另一方面要做为Controller。MVP的出现,则是分解Activity的功能,将其只做为一个View。
个人觉得MVP最大的缺点就是导致代码量太大了。
Demo中的MVP
test/java/{应用包名}
下面, 关于测试中用到的Mockito
后面会介绍执行Case
Google是这么说的:
贴个图就清楚了
再来看Mockito的基本使用
可以参看官方文档,这里只简单介绍一下。 采用
Mockito
来mock一个对象时, 既可以像上面的例子写的那样采用注解的方式,也可以用Mockito
中的方法。 如:Mock一个接口
Mock 一个具体对象
设置方法的预期返回值
此时如果调用view.getUserName()返回的将会是"James". 当然还可以指定异常,如(这个例子来自官方):
验证方法是否被调用
如上面例子中验证
startMainActivity
这个方法是否被调用验证超时时间