Android单元测试之AssertJ框架

2017-06-01  |   Android   android, assertj, test

回到顶部

前序

  上一篇Android单元测试文章说到如果使用Junit给我们提供的Assert去对比Intent,那就需要每个成员都对比一次,十分不方便,今天给大家带来一个十分便利的框架AssertJ,由于这个框架本身是给Java使用的,我们可以直接使用针对Android设计的AssertJ-Android框架。这个框架官方说明中写道“... aims to make it even easier to test Android”(致力于让安卓测试更简单),它和Assertj原版的比较可以看看官方的说明,这个不是本文的重点,这里就不多说了。

Gradle依赖

  首先当然是引入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的自动提示功能很快你就能找到需要的方法了。

自定义Assertions

  实际上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

上一篇:Android单元测试之Robolectric框架
下一篇:Android中的Lambda表达式详解