模拟时单元测试协同程序nullpointerexception



我正在单元测试以下类

class LoadTrendingSearchUseCaseImp @Inject constructor(
private val searchCriteriaProvider: SearchCriteriaProvider,
private val coroutineDispatcherProvider: CoroutineDispatcherProvider
) : LoadTrendingSearchUseCase {
override suspend fun execute(): List<String> {
return withContext(coroutineDispatcherProvider.io()) {
searchCriteriaProvider.provideTrendingSearch().trendingSearches
}
}
}
interface SearchCriteriaProvider {
suspend fun provideTrendingSearch(): CatalogSearchPage
}
class SearchCriteriaProviderImp() : SearchCritieraProvider {
override suspend fun provideTrendingSearch(): CatalogSearchPage {
return withContext(coroutineDispatcherProvider.io()) {
/* long running task */
}
}
}
interface CoroutineDispatcherProvider {
fun io(): CoroutineDispatcher = Dispatchers.IO
fun default(): CoroutineDispatcher = Dispatchers.Default
fun main(): CoroutineDispatcher = Dispatchers.Main
fun immediate(): CoroutineDispatcher = Dispatchers.Main.immediate
fun unconfined(): CoroutineDispatcher = Dispatchers.Unconfined
}
class CoroutineDispatcherProviderImp @Inject constructor() : CoroutineDispatcherProvider

这是我的实际测试:

class LoadTrendingSearchUseCaseImpTest {
private val searchCriteriaProvider: SearchCriteriaProvider = mock()
private val coroutineDispatcherProvider = CoroutineDispatcherProviderImp()
private lateinit var loadTrendingSearchUseCaseImp: LoadTrendingSearchUseCaseImp
@Before
fun setUp() {
loadTrendingSearchUseCaseImp = LoadTrendingSearchUseCaseImp(
searchCriteriaProvider,
coroutineDispatcherProvider
)
}
@Test
fun `should provide trending searches`() {
runBlockingTest {
// Arrange
// EXCEPTION HERE                whenever(searchCriteriaProvider.provideTrendingSearch().trendingSearches).thenReturn(
emptyList()
)
// Act
val actualResult = loadTrendingSearchUseCaseImp.execute()
// Assert
assertThat(actualResult).isEmpty()
}
}
}

实际错误消息:

java.lang.NullPointerException
.product_search.usecase.imp.LoadTrendingSearchUseCaseImpTest$should provide trending searches$1.invokeSuspend(LoadTrendingSearchUseCaseImpTest.kt:30)

您试图在存根方法时链接调用。

whenever(searchCriteriaProvider.provideTrendingSearch().trendingSearches)
.thenReturn(emptyList())

在存根期间,实际的方法被调用。

  • searchCriteriaProvider.provideTrendingSearch()返回null,因为此调用尚未存根
  • 后续调用null.trendingSearches导致NPE

您需要在链中截取每个调用

whenever(searchCriteriaProvider.provideTrendingSearch())
.thenReturn(catalogSearchPage)
whenever(catalogSearchPage.trendingSearches)
.thenReturn(emptyList())

显然,这是假设

  • catalogSearchPage也是一个mock
  • trendingSearches是一个属性

或者,您可以为catalogSearchPage构造一个POJO,并在第一次存根中返回它。

最新更新