Kotlin开发Android应用踩坑记录

最近在搞Android内部培训,指定使用Kotlin,在使用过程中遇到一些坑,包括跟第三方库结合使用,单元测试等方面,简单记录下来,以备日后查阅,好记性不如烂笔头!(以后会不断更新更多的踩坑记录)

与Java语言实现的三方库集成的坑

  1. ButterKnife
    使用 Kotlin 开发 Android 应用时,要在预编译阶段处理注解必须使用kotlin-kapt,所以代码build.gradle的配置就是这样的啦
apply plugin: 'kotlin-kapt'
......
kapt 'com.jakewharton:butterknife-compiler:8.8.1'

这里的坑: 如果你一不小心按照原来Java的习惯使用了annotaionProcessor,并且已经编译过代码,你会发现注解根本无法被处理。这个时候即便你将 annotaionProcessor换成kapt也无济于事,你必须要先执行clean project再编译,才能让注解被正常处理!

与测试框架一起使用时的坑

  1. 与 Mockito 一起使用,测试无法得到预期的结果
    1)在使用Mockito框架时我们常常会用注解@Mock@InjectMock来进行依赖对象的创建和注入。
    2)在 Java 版本的测试代码中,我们在 setUp 函数中还需要调用MockitoAnnotations.initMocks(this)来手动触发这些依赖注解的处理流程。
    注意: 在使用 Java 写 Mockito 测试用例的时候这一步是必须的!(请参考Mockito 的 API 文档)

    坑:
    表现: 在 Kotlin 版本的 Mockito 测试代码中,如果做了第二步操作,测试用例将会大面积失败,你甚至会质疑这个框架的正确性,或者会质疑 Mockito 是否能跟 Kotlin 一起使用。

    原因: 不及惊慌,原因其实很简单,在 使用 Kotlin 编写 Mockito 测试用例的时候,注解的处理会被自动触发,如果再调用一次 MockitoAnnotations.initMocks(this) ,使用 @InjectMock 标注的被测目标对象所依赖的对象将会被第二次创建并被测目标对象。因此被测目标对象在运行中使用的是第二次创建的依赖对象,而我们的测试代码中的使用 @Mock标注的依赖对象却并没有被使用。所以,你在代码中使用这些依赖对象所进行的各种验证操作基本都不会通过测试!

    解决方案: 去掉MockitoAnnotations.initMocks(this)这行代码。在 Koltin 代码编译成 class 文件时,编译器已经显示地在初始化测试类的时候调用了它!!

  2. 与 Espresso 一起使用
    坑:
    在 Espresso 测试代码中我们会用到 ActivityTestRule

    @Rule
    var mActivityRule = ActivityTestRule(MainActivity::class.java)
    

    在运行时会报错告诉你

    org.junit.internal.runners.rules.ValidationError: The @Rule 'mActivityRule' must be public.
    

    原因:
    这里的问题是,经过 Koltin编译器编译以后的字节码中 mActivityRule并不是 public 的,而是private访问权限的。

    解决方案:
    给变量加上一个 @JvnField 注解,编译以后的 mActivityRule 就会保持在 Kotlin 中的 public 访问权限啦!(参考官方文档)

    @Rule
    @JvmField
    var mActivityRule = ActivityTestRule(MainActivity::class.java)
    

后记:

后续会陆续更新踩坑记录!!

你可能感兴趣的:(Kotlin开发Android应用踩坑记录)