【问题标题】:Location object return null while testing with Junit5使用 Junit5 进行测试时位置对象返回 null
【发布时间】:2021-04-27 03:28:14
【问题描述】:

我必须测试当前位置是否在某个特定位置附近。在我的测试类中,我试图通过设置经度和纬度来创建该特定位置,在应用程序中,这些数据来自后端。在我的测试课中,我手动输入它们。因为我的函数重复了太多次,所以我不得不使用 Junit5 提供的 ParametizedTest。但是使用 Junit5 使我无法 RunWith(RoboElectricTestRunner.class)。相反,我开始使用 mannodermaus 插件使用 Junit5 进行 Android 测试。它带来了另一个我无法弄清楚的问题,我的 Location 对象现在返回 null 而不是设置 lon 和 lat

 private fun strings(): Stream<String?>? {
            return Stream.of( "foo", "bar")
        }
    
        @ParameterizedTest
        @MethodSource("strings")
        fun updateLocation(input: String)  {      
    
            var lat = 12.494831
            var lon = 83.49899
            val startLocation = Location("start")
            startLocation.latitude = lat
            startLocation.longitude = lon
    
            **println("startLocation = $startLocation") **//returns null****
    }

在它工作正常之前,当我使用 JUnit4 和 @RunWith(RobolectricTestRunner.class) 时。现在我使用带有 mannodermaus 插件的 Junit5。

我的 build.gradle 文件如下所示。

  apply plugin: 'de.mannodermaus.android-junit5'

apply from: rootProject.file('buildscripts/sonar.gradle')

android.buildFeatures.dataBinding = true

dependencies {

    //kotlin
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$rootProject.kotlinVersion"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutinesVersion"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutinesVersion"

    // External libraries
    implementation "com.jakewharton.timber:timber:$rootProject.timberVersion"

    // Android Architecture Components
    api "androidx.lifecycle:lifecycle-extensions:$rootProject.lifecycleVersion"
    api "androidx.lifecycle:lifecycle-common-java8:$rootProject.lifecycleVersion"

    implementation 'joda-time:joda-time:2.10.5'

    //testing libraries
    testImplementation "org.junit.jupiter:junit-jupiter-api:5.7.0"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.7.0"
    testImplementation "org.junit.jupiter:junit-jupiter-params:5.7.0"
    testCompile "org.robolectric:robolectric:4.3"
    testImplementation "org.mockito:mockito-junit-jupiter:2.19.0"
    androidTestImplementation "androidx.test.ext:junit:$rootProject.extjunitVersion"
    androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.espressoVersion"

}

android {
    compileOptions {
        sourceCompatibility = '1.8'
        targetCompatibility = '1.8'
    }

    testOptions {
        testOptions {
            unitTests.returnDefaultValues = true
            junitPlatform {
                filters {
                    includeTags "slow"
                    excludeTags "integration"
                }
                debugFilters {
                    includeTags "integration"
                }
            }
        }
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }

    //If your minSdkVersion is 24 or higher, then your issue will be resolved on its own, because VectorDrawables have full support starting with this API.
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

【问题讨论】:

    标签: android junit4 junit5 android-testing android-location


    【解决方案1】:

    嗯,我想出了如何使用 Mockito 来做到这一点:

    val mockInitializer: MockedConstruction.MockInitializer<Location> = MockedConstruction.MockInitializer { mock, _ ->
       doReturn(12.494831).`when`(mock).latitude
       doReturn(83.49899).`when`(mock).longitude
    }
    
    Mockito.mockConstruction(Location::class.java, mockInitializer)
    

    然后您可以初始化一个位置,该位置将是一个带有初始化指示的模拟。


    额外:

    您可能需要多个具有不同值的模拟。假设您需要 2 个具有不同值的模拟初始化程序。然后你可以这样做:

    val locationMockList = mutableListOf( //Pair<Lat:Double, Long:Double>
        11.0 to 22.0,
        33.0 to 44.0
    )
    
    val mockInitializer: MockedConstruction.MockInitializer<Location> = 
    MockedConstruction.MockInitializer { mock, _ ->
        locationMockList.removeFirstOrNull()?.let{
            doReturn(it.first).`when`(mock).latitude
            doReturn(it.second).`when`(mock).longitude
        }
    }
    
    Mockito.mockConstruction(Location::class.java, mockInitializer)
    

    当然,如果您尝试初始化第三个位置,这将引发异常,但这只是一个示例。有了这个 sn-p,我相信您可以弄清楚如何调整它来解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-01
      • 2017-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-29
      • 1970-01-01
      相关资源
      最近更新 更多