TrendingViewModelTest
@RunWith(JUnit4::class)
class TrendingViewModelTest {
private lateinit var trendingRepository: TrendingRepository
private lateinit var trendingViewModel: TrendingViewModel
@get:Rule
val schedulers = RxImmediateSchedulerRule()
@Before
fun setUp() {
trendingRepository = mock(TrendingRepository::class.java)
trendingViewModel = TrendingViewModel(trendingRepository)
}
@Test
fun testWithNetwork() {
trendingViewModel.isConnected = true
trendingViewModel.fetchTrendingRepos()
verify(trendingRepository, times(1)).getTrendingRepos()
}
//...
}
趋势视图模型
fun fetchTrendingRepos() {
if (isConnected) {
loadingProgress.value = true
compositeDisposable.add(
trendingRepository.getTrendingRepos().subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ response ->
run {
loadingProgress.value = false
},
{ error ->
loadingProgress.value = false
}
)
)
}
class RxImmediateSchedulerRule : TestRule {
override fun apply(base: Statement?, description: Description?): Statement {
return object : Statement() {
@Throws(Throwable::class)
override fun evaluate() {
RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() }
RxJavaPlugins.setComputationSchedulerHandler { Schedulers.trampoline() }
RxJavaPlugins.setNewThreadSchedulerHandler { Schedulers.trampoline() }
RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
try {
base?.evaluate()
} finally {
RxJavaPlugins.reset()
RxAndroidPlugins.reset()
}
}
}
}
}
class TrendingRepositoryImpl @Inject constructor(
val apiService: GitHubApi,
val trendingDao: AppDao
) : TrendingRepository {
override fun getTrendingRepos(): Single<List<TrendingRepo>> {
return apiService.getTrendingGits()
}
}
TrendingRepository:
interface TrendingRepository {
fun getTrendingRepos(): Single<List<TrendingRepo>>
}
在FetchTrendingRepos()
内部启动了一个Rxjava调用,它还挂钩到“AndroidSchedulers.MainThread()”,这可能是导致它的原因。
在更新LiveData
值时,还应添加@get:rule var rule:TestRule=InstantTaskExecutorRule()
。
不要忘记在build.gradle文件中添加以下内容:
dependencies {
// ...
testImplementation "androidx.arch.core:core-testing:2.1.0"
}
此外,相应地更改测试代码,以避免NullPointerException
:
@Test
fun testWithNetwork() {
trendingViewModel.isConnected = true
Mockito.`when`(trendingRepository.fetchTrendingRepos()).thenReturn(Single.just(listOf<TrendingRepo>()))
trendingViewModel.fetchTrendingRepos()
verify(trendingRepository, times(1)).getTrendingRepos()
}
mockito.when()
允许您在每次调用模拟方法时执行不同的操作。如果不使用它,您可能会看到可能的NullPointerException
取决于您的测试函数。
我遇到了一个挑战,当我单独运行测试时,测试通过了,但当我运行所有测试时,测试失败了,它会显示以下错误消息: java.lang.RuntimeException:Android.os.Looper中的方法getMainLooper未被嘲弄。详见http://g.co/androidstudio/not-mocked。 在Android.os.looper.GetMainLooper(looper.
在helper类的静态方法中调用时,它会抛出一个NPE。我所做的是嘲笑MarkupMaker和它的返回值(一个Markup实例)。最后,我希望调用标记实例的。无论我做什么-的调用都是抛出一个NPE。我找不到任何文档告诉我如何在spock中详细模拟方法调用值。 编辑:我添加了示例。的调用返回null,即使我在spock测试中对其进行了嘲弄。 test.groovy java(执行模拟对象的方法) j
正在测试的类: 下面是测试代码。我模拟了测试中的类class,并覆盖了方法getFruits的返回值。但是当我运行mock时,我没有得到预期的mock返回值。Easymock可以将返回值替换为被测试类的方法,如果这些方法是显式模拟的。当我模拟真实的对象方法时,如何获得模拟的返回值。
尝试为使用的演示者运行JUnit测试时,遇到RuntimeException。 由于它们是纯JUnit测试,而不是Android instrumentation测试,因此它们没有访问Android依赖项的权限,导致我在执行测试时遇到以下错误:
我正在为类编写一个单元测试,该类如下所示: 我想编写一个简单的单元测试,它将方法存根(这样它就不会实际触发并命中数据库),但它允许我验证调用是否最终执行。Mockito似乎是这份工作的合适工具。 这似乎是一个很好的游戏计划(至少对我来说)。但当我实际编写代码时,在测试方法的第2行(行)出现以下编译器错误: 类型Mockito中的(T)不适用于参数(void)时的方法 我看到Mockito无法模拟返
是否可以用Spock模拟java中的静态方法?我知道模拟静态groovy方法是可能的,但无法使其适用于Java方法。