JUnit单元测试
单元测试的目的
- 定位bug
- 保证最小单元内的实现方式是正确的
- 提高代码健壮性
基于Jvm的单元测试 —— JUnit
只在本地的Jvm虚拟机上运行,不依赖Android环境,可以最小化执行时间。
JUnit的使用
在module的build.gradle中的dependencies块中声明testImplementation ‘junit:junit:4.12’
apply plugin: '...'
...
android {...}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
...
}
然后在src目录下创建test目录,专用存放Jvm单元测试类。
JUnit中常用的注解
- @Test注解 用于声明需要测试的方法。
@Test注解可以带两个参数:
- @Test (expected = Throwable.class)。测试方法若没有抛出指定的Throwable类型(子类也可以),测试不通过。
/**
* 如果测试该方法时产生一个ArithmeticException的异常,则表示测试通过
* 你可以改成int i = 1 / 1;运行时则会测试不通过-因为与你的期望的不符
*/
@Test(expected = ArithmeticException.class)
public void testDivisionWithException() {
int i = 1 / 0;
}
/**
* 运行时抛出一个IndexOutOfBoundsException异常才会测试通过
*/
@Test(expected = IndexOutOfBoundsException.class)
public void testEmptyList() {
new ArrayList<>().get(0);
}
- @Test(timeout=200) 。带该参数可以测试方法的性能,若方法执行超过200ms,测试不通过
@Test(timeout = 200)
public void testTimeOut() {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
- @Before。在每个测试之前执行,用于初始化类,读输入流等,在一个测试类中,每个@Test方法的执行都会触发一次调用。
@After。在每个测试之后执行,用于清理测试环境数据,在一个测试类中,每个@Test方法的执行都会触发一次调用。
@Before
public void before() {
System.out.println("测试方法之前调用,用于初始化");
}
@Test
public void test() {
System.out.println("我是测试方法");
}
@After
public void after() {
System.out.println("测试方法之后调用,用于释放资源");
}
测试方法
一般使用org.junit.Assert包下的assertEquals(变量1, 变量2)来判断2个变量是否相同,相同则通过测试。或者使用assertThat(T, is())方法来判断返回值是否相同。
//可简写为 assertTrue(validMobile("13387654321"));
assertEquals(validMobile("13387654321"), true);
assertThat(validMobile("13387654321"), is(true));
Mockito
Mockito的作用
- 验证某个对象的行为。
- 验证某个对象的行为的调用次数。
Mockito优点
- 能够将待测试代码与其依赖进行隔离。
- 让一些对Android存在一定依赖的测试代码,运行在本地JVM上。
Mockito的使用场景
- 待测试代码对Android有较小的依赖。
- 开发者希望待测试代码与其依赖隔离开。
引入Mockito
dependencies {
testImplementation 'junit:junit:4.12' //必须引入
testImplementation 'org.mockito:mockito-core:1.10.19'
android