【发布时间】:2020-10-16 16:45:14
【问题描述】:
我正在尝试测试存储库ExpensesRepository
class ExpensesRepository @Inject constructor(
private val store: DataStore
) : AbstractRepository<Expense> {
override fun get(offset: Int, limit: Int): List<Expense?> =
store.getAll(offset, limit)
override fun get(key: String): Expense? = store.getOne(key = key)
override fun create(input: Expense) =
store.create(key = input.key, element = input)
override fun delete(key: String) = store.remove(key = key)
override fun update(
key: String,
update: Expense
): Expense =
store.update(key = key, element = update)
override fun removeAll() = store.flush()
}
在测试套件中,我使用 mockito 模拟了 store 参数,然后我将该模拟的方法 getOne(String) 存根以从我的固定装置返回一个费用对象。
这是我的测试套件
class ExpensesRepositoryTest {
@get:Rule
var instantTaskExecutorRule = InstantTaskExecutorRule()
private lateinit var repository: ExpensesRepository
private val dataStore = mock<DataStore>()
private val expense = Expense(
"key",
1,
"name",
"date",
12.12
)
private val expenseList = listOf(
expense,
expense,
expense
)
private val dummyKey = "expense_key"
@Before
fun setup() {
repository = ExpensesRepository(dataStore)
}
@Test
fun `should get an item with existing key`() {
whenever(dataStore.getOne<Expense>(dummyKey)).thenReturn(expense)
val result = repository.get(dummyKey)
verify(dataStore, Times(1)).getOne<Expense>(dummyKey)
assertThat(result).isEqualTo(expense)
}
}
当我运行测试时它失败了,因为 NullPointerException 并且那是 DataStore 调用我之前应该存根的函数 getOne(String) 的时候。如果它在这里有帮助,那就是DataStore 类
class DataStore(val store: Persistence, val gson: Gson) {
inline fun <reified R : Persistable> getAll(
offset: Int,
limit: Int
): List<R?> =
store.get(offset, limit).map { it.maybeMapTo<R>(mapper = gson) }
inline fun <reified R : Persistable> getOne(key: String): R? =
store.get(key).maybeMapTo<R>(mapper = gson)
fun create(key: String, element: Persistable) {
store.create(
key = key,
element = when (store) {
is JsonBased -> gson.toJson(element)
else -> element
}
)
}
inline fun <reified R : Persistable> update(
key: String,
element: R
): R {
return store.update(key, element) as R
}
fun remove(key: String) {
store.remove(key)
}
fun flush() {
store.flush()
}
}
我在这里做错了吗?
【问题讨论】:
-
为什么不模拟
Persistence类并将其注入DataStore? -
在这种情况下,DataStore 成为一个真实的实例,而不是一个模拟。理想情况下,只有被测类才是真实对象。因此,如果您这样做,您将不得不监视 DataStore,而我不想这样做。
标签: unit-testing kotlin junit mockito