上一篇Android单元测试文章说到如果使用Junit给我们提供的Assert去对比Intent,那就需要每个成员都对比一次,十分不方便,今天给大家带来一个十分便利的框架AssertJ,由于这个框架本身是给Java使用的,我们可以直接使用针对Android设计的AssertJ-Android框架。这个框架官方说明中写道“... aims to make it even easier to test Android”(致力于让安卓测试更简单),它和Assertj原版的比较可以看看官方的说明,这个不是本文的重点,这里就不多说了。
首先当然是引入AssertJ-Android,直接在app的build.gradle中添加:
testCompile 'com.squareup.assertj:assertj-android:1.1.1'
如果遇到冲突问题,比如:
Conflict with dependency 'com.android.support:support-annotations' in project ':app'. Resolved versions for app (23.0.1) and test app (22.2.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
可以排除部分模块,如上述的support-annotations:
testCompile( 'com.squareup.assertj:assertj-android:1.1.1' ,{
exclude group: 'com.android.support', module: 'support-annotations'
})
值得注意,Support-v4和Appcompat也是需要单独的依赖:
testCompile 'com.squareup.assertj:assertj-android-support-v4:1.1.1'
testCompile 'com.squareup.assertj:assertj-android-appcompat-v7:1.1.1'
AssertJ-Android还支持很多其他库,这些依赖都可以在官方文档找到,这里不一一说明。
由于AssertJ比较简单,这里就直接给一个简单例子说明下:
Assertions.assertThat(actual).isEqualTo(expected);
上面的是比较两个对象的断言,注意assertThat传入的是actual实际对象,这个容易和Junit的搞混。
注意AssertJ-Android包含了AssertJ和扩展的Android API,分别对应:
org.assertj.core.api.Assertions
org.assertj.android.api.Assertions
使用的时候要注意包名,否则可能会找不到方法。
前文说到,使用Junit的Assert判断两个Intent比较麻烦,下面我们以Intent为例子说明链式判断:
Assertions.assertThat(actual)
.hasComponent(expected.getComponent())
.hasAction(expected.getAction())
.hasFlags(expected.getFlags());
首先Assertions.assertThat会根据actual的类型返回对应的AbstractAssert子类,比如这里返回的是IntentAssert,而IntentAssert里面每个方法都是返回IntentAssert,这样可以做到链式调用,快速判断两个对象的属性。而且针对不同的对象他给出的方法也不一样,比如说MapAssert它身上有contains等方法专门针对Map对象来判断,十分方便。这里就不一样介绍了,使用IDE的自动提示功能很快你就能找到需要的方法了。
实际上AssertJ-Android就是基于AssertJ基础上添加了大量Android相关API的自定义Assertions。下面我们也来为我们自己写的类自定义Assertions。
首先假设我们有一个UserInfo类需要我们自定义Assert类:
public class UserInfo {
private String userName;
//here is getter and setter...
}
然后我们定义一个UserInfoAssert类,前面说过,这些Assert类都是继承自AbstractAssert类,注意泛型即可:
public class UserInfoAssert extends AbstractAssert<UserInfoAssert, UserInfo> {
public UserInfoAssert(UserInfo actual) {
super(actual, UserInfoAssert.class);
}
public UserInfoAssert hasUserName() {
isNotNull();//防止actual为空
String userName = actual.getUserName();
if (TextUtils.isEmpty(userName)) {
failWithMessage("Expected username was not null but was null.");
}
return this;
}
}
最后需要自定义一个Assertions类给我们提供访问UserInfoAssert:
public class Assertions {
public static UserInfoAssert assertThat(UserInfo actual) {
return new UserInfoAssert(actual);
}
}
完了之后就可以使用类似AssertJ的写法了:
Assertions.assertThat(new UserInfo()).hasUserName();
上述代码如无意外就会抛出一个错误,需要注意的只是Assertions的导包问题。
经过一系列单元测试框架介绍,Android单元测试的基本内容就这些了,比如说如果快速编写单元测试用例等等这些,如果需要深入了解的话可以去看看一些相关的书籍。
Android单元测试之JUnit框架: https://maxwell-nc.github.io/android/junitTest.html
Android单元测试之Mockito框架: https://maxwell-nc.github.io/android/mockitoTest.html
Android单元测试之Robolectric框架: https://maxwell-nc.github.io/android/robolectricTest.html
Android单元测试之AssertJ框架: https://maxwell-nc.github.io/android/assertjTest.html
原创文章,欢迎转载,请保留出处。有任何错误、疑问或者建议,欢迎指出。
请注明文章出自于:https://maxwell-nc.github.io/android/assertjTest.html