Android 将Mockito core更新到3.0.0版后,Mockito在SharedReferences中返回null

Android 将Mockito core更新到3.0.0版后,Mockito在SharedReferences中返回null,android,unit-testing,kotlin,mockito,Android,Unit Testing,Kotlin,Mockito,考虑以下测试类: @RunWith(MockitoJUnitRunner::class) class DatabaseManagerTest { private var someStringValue = "test" private var mockDatabaseManager: DatabaseManager? = null @Mock internal var mockSharedPreferences: SharedPreferences? = nul

考虑以下测试类:

@RunWith(MockitoJUnitRunner::class)
class DatabaseManagerTest {

    private var someStringValue = "test"
    private var mockDatabaseManager: DatabaseManager? = null
    @Mock
    internal var mockSharedPreferences: SharedPreferences? = null
    @Mock
    internal var mockEditor: SharedPreferences.Editor? = null

    @Before
    fun initMocks() {
         mockDatabaseManager = createMockSharedPreference()        
    }

    private fun createMockSharedPreference(): DatabaseManager {
        `when`<String>(
            mockSharedPreferences?.getString(
               Matchers.eq(DatabaseManager.SOME_UNIQUE_KEY),
               Matchers.anyString()
            )
        ).thenReturn(someStringValue)

        `when`(mockEditor?.commit()).thenReturn(true)

        `when`<SharedPreferences.Editor>(mockSharedPreferences?.edit()).thenReturn(mockEditor)

        return DatabaseManager(mockSharedPreferences!!)
    }

    @Test
    fun sharedPreferencesHelperUpdateAndReadStoredInformation() {
        val success = mockDatabaseManager?.insert(someStringValue)

        assertThat(
            "Checking that update method returns true",
            success, `is`(true)
        )

        val savedSharedPreferenceEntry = mockDatabaseManager?.readSomeValue()

        assertThat(
           "Checking that value is stored correctly",
           someStringValue,
           `is`(equalTo(savedSharedPreferenceEntry))
        )
    }
}
当使用旧的Mockito库(1.10.19)时,测试通过

在将mockito core切换到3.0.0时,我收到了两条不推荐使用的警告:
@RunWith(MockitoJUnitRunner::class)
匹配器
。解决这两个不推荐使用的警告后,我希望readSomeValue()返回“test”,但readSomeValue()返回
null

//    testImplementation 'org.mockito:mockito-core:3.0.0'
    testImplementation 'org.mockito:mockito-core:1.10.19'

首先,您应该更改测试的第一位,如下所示:

@Mock
lateinit var mockSharedPreferences: SharedPreferences
@Mock
lateinit var mockEditor: SharedPreferences.Editor

@Before
fun initMocks() {
    MockitoAnnotations.initMocks(this)
    mockDatabaseManager = createMockSharedPreference()
}
您没有初始化模拟对象,因此成员变量没有赋值

其次,SharedReferences是一个android组件,无法按照您尝试的方式进行单元测试。在您尝试插入内容的情况下,测试insert函数的响应,该函数始终为true。然后,您尝试获取该值。您不应该测试框架,而应该测试代码

如果你想这样构造你的测试,我会推荐

不过,我会建议您以不同的方式构建测试,比如验证在您期望的时候调用了正确的东西。比如说,

@Test
fun `shared preferences insert`() {
    mockDatabaseManager?.insert(someStringValue)

    Mockito.verify(mockSharedPreferences).edit()
    Mockito.verify(mockEditor).putString(
        Mockito.eq(DatabaseManager.SOME_UNIQUE_KEY),
        Mockito.eq(someStringValue)
    )
    Mockito.verify(mockEditor).apply()
}


@Test
fun `shared preferences readSomeValue`() {
    mockDatabaseManager?.readSomeValue()

    Mockito.verify(mockSharedPreferences).getString(
        Mockito.eq(DatabaseManager.SOME_UNIQUE_KEY),
        Mockito.isNull()
    )
}

解决这两个不推荐使用的警告后[…]

还请分享您如何解决这些警告。因为当我改变时:

           Matchers.eq(DatabaseManager.SOME_UNIQUE_KEY),
           Matchers.anyString()


要删除关于未使用mocking的错误,请使用org.mockito:mockito core:3.0.0通过测试。接受的答案是将mockito core更改为3.0.0。此外,这个建议是正确的,我确实在做一个无用的测试,现在我正在测试我的实际代码,而不是框架。
           Matchers.eq(DatabaseManager.SOME_UNIQUE_KEY),
           Matchers.anyString()
           eq(DatabaseManager.SOME_UNIQUE_KEY),
           any<String>()
    `when`(mockEditor?.commit()).thenReturn(true)