在 Kotlin 中,针对单元测试构建 BuildConfigField 模拟。

10

我正在尝试全面涵盖一个Kotlin Android库,并遇到了有关自定义BuildConfig变量的问题,通常称为buildConfigField

我想模拟这个变量以测试truefalse值。

Gradle文件摘录:

android {
    defaultConfig {
        buildConfigField "boolean", "ENABLE_LOG", "false"
    }
    flavorDimensions "log"
    productFlavors {
        loggable {
            buildConfigField "boolean", "ENABLE_LOG", "true"
            dimension "log"
        }
        notloggable {
            dimension "log"
        }
    }
}

待测试的 Kotlin 函数摘录:

fun buildClient(): MyClient {
    var myClientBuilder : MyClient.Builder = MyClient.Builder();

    if (BuildConfig.ENABLE_LOG) {
        val interceptor = LoggingInterceptor();
        interceptor.setLevel(LoggingInterceptor.Level.ALL);
        myClientBuilder.addInterceptor(interceptor);
    }

    return myClientBuilder.build()
}

单元测试:

@Test
fun buildClient_enableLog_oneInterceptor() {
    // GIVEN
    Mockito.mock(BuildConfig::class.java)
    Mockito.doReturn(true).`when`(BuildConfig.ENABLE_LOG)

    // WHEN
    val myClient = myService!!.buildClient()

    // THEN
    assertNotNull(myClient)
    assertNotNull(myClient.interceptors())
    assertEquals(1, myClient.interceptors().size)
}

我尝试了不同的方法,但从未成功。如果有人已经完成了这项工作,它可以帮助我很多(我想也会帮助其他人)。

谢谢


6
为什么不将变量 BuildConfig.ENABLE_LOG 作为参数发送到您的函数中?这样,您可以通过调用 buildClient(enableLog: Boolean) 来模拟测试。或者,在包含该函数的类的构造函数中发送它以将其拉入类级别?或者使用依赖注入将变量注入到您的类中? - Usama K. Zafar
我在文档中找到了解决方案:https://developer.android.com/studio/test/ 您可以在此处检查代码:https://github.com/BapNesS/android-unittests-demo - BapNesS
@BaptisteCarlier,您能否写一个带有详细信息的答案?跟随链接到您的代码很困难,因为那里有许多其他类需要检查以获取特定问题的答案。我认为只需要一个简单的片段就可以完成工作。 - Reaz Murshed
他的两个链接都无法访问,看起来像是垃圾评论。 - AndroidEngineX
3个回答

5
ReflectionHelpers.setStaticField(BuildConfig::class.java, "ENABLE_LOG", true)

2
我应该从哪里导入ReflectionHelpers? - Michał Jabłoński
2
"ReflectionHelpers" 是 Robolectric 生态系统的一部分。 - arkascha
1
这对我不起作用。配置属性没有改变。 - ciaranodc
@ciaranodc - 你能让这个工作起来了吗? - dazza5000
最好创建一个 BuildConfig 的包装器并从该类中获取值,这样您就可以在任何地方模拟或注入它。 - Dev Soni
使用这个方法时出现异常。java.lang.RuntimeException: java.lang.IllegalAccessException: 无法将静态的 final java.lang.Boolean 字段 ca.manulife.MobileBanking.BuildConfig.AML_ENABLED 设置为 java.lang.Boolean - Arpit Patel

0

默认情况下,所有测试都针对调试构建类型运行。您可以通过在模块级别的build.gradle文件中使用testBuildType属性来将其更改为其他构建类型。例如,如果您想针对“staging”构建类型运行测试,请按以下代码片段所示编辑文件。

android { ... testBuildType "staging" } 但是这会导致其他选项失败


0
有点晚了,但这是您应该测试与BuildConfig文件相关的任何内容的方式。 对于您的应用程序的每个变体,都会生成 BuildConfig.java。在您的情况下,至少有4种变体。
  1. LoggableDebug
  2. LoggableRelease
  3. NotloggableDebug
  4. NotloggableRelease

选项3和4中的 ENABLE_LOG 将为false。如果想进行单元测试,建议在 src / testNotLoggable / java / com / ... / TestFile.java 中编写单元测试。

在那个 TestFile.java 中,您的 BuildConfig.ENABLE_LOG 应该为 false。

您可以检查每个变体的 BuildConfig.java 文件,位于 / build / source / buildConfig / flavorname / debug / com / project / .. / BuildConfig.java 下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接