考虑下面的测试类:
@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))
)
}
}
这是数据库类:
class DatabaseManager(private val preferences: SharedPreferences) {
companion object {
const val SOME_UNIQUE_KEY = "some_unique_key"
}
fun insert(response: String): Boolean {
try {
val editor = preferences.edit()
editor.putString(SOME_UNIQUE_KEY, response)
editor.apply()
} catch (e: Exception) {
e.printStackTrace()
}
return true
}
fun readSomeValue(): String? {
return try {
val someValue = preferences.getString(SOME_UNIQUE_KEY, null)
someValue
} catch (e: Exception) {
e.printStackTrace()
null
}
}
}
当使用旧的 Mockito 库(1.10.19)时,测试通过。
将 mockito-core 切换到 3.0.0 时,我收到 2 个已弃用的警告:@RunWith(MockitoJUnitRunner::class)
和 Matchers
。解决了这 2 个已弃用的警告后,我期望 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()
}
您没有初始化您的模拟对象,因此没有为成员变量赋值。
其次,SharedPreferences 是一个 android 组件,无法按照您尝试的方式进行单元测试。在您的情况下,您正在尝试插入一些东西,测试您的 insert 函数的响应,它始终是 true 。然后,您正在尝试获取该值。您不应该测试框架,而应该测试您的代码。
如果你想像那样构建你的测试,我会推荐 Robolectric .
不过,我会建议以不同的方式构建您的测试,例如验证是否在您期望的时候调用了正确的东西。例如,
@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()
)
}
关于android - 将 mockito-core 更新到版本 3.0.0 后,Mockito 在 SharedPreferences 中返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58205389/