gpt4 book ai didi

android - 测试特定用例时 TestScheduler 不工作

转载 作者:行者123 更新时间:2023-11-28 20:27:31 25 4
gpt4 key购买 nike

我正在测试单个用例。但是测试观察者不会在测试环境中发出任何东西。

  • 即使我将 subscribeOn()Schedulers.newThread() 更改为TestScheduler() 仍然测试失败。我很困惑。我不知道是什么我在这里做错了吗?
  • 如果我删除 subscribeOn,observeOn 方法然后测试成功通过。然后TestScheduler() 的实际用途是什么?

以下是UseCase.kt文件

abstract class UseCase<T>(val postExecutionThread: PostExecutionThread) {

abstract fun buildUseCaseBuilder(): Observable<T>

/**
* execute method for observables
*/
open fun execute(): Observable<T> {
return buildUseCaseBuilder()
.subscribeOn(Schedulers.newThread())
.observeOn(postExecutionThread.getScheduler())
}
}

在测试类之后加上上面的被测类

class UseCaseTest {

val postExecutionThread=Mockito.mock(PostExecutionThread::class.java)
val result: String="test"
val testObserver=TestObserver<String>()

@Before
fun setUp() {
_when(postExecutionThread.getScheduler()).thenReturn(TestScheduler())
}

@Test
fun `test execute method of use case`() {
println(" thread type ${postExecutionThread.getScheduler()}")

//test fail
//java.lang.AssertionError: Value count differs; Expected: 1 [test], Actual: 0 [] (latch = 1, values = 0, errors = 0, completions = 0)
TestUseCase(postExecutionThread).execute().test()
.assertResult(result)

//subscriber not print any thing
TestUseCase(postExecutionThread).execute().subscribe{
println("called $it")
}
}

inner class TestUseCase(postExecutionThread: PostExecutionThread?) : UseCase<String>(postExecutionThread!!) {
override fun buildUseCaseBuilder(): Observable<String> {
return Observable.just(result)
}
}
}

最佳答案

问题是,您的测试是在您使用 subscribeOn()observeOn() 指定的线程以外的线程上运行的。你想要的是让测试和被测试的代码在同一个线程上同步运行,而不管 subscribeOn()/observeOn() 中指定了什么。

您可以使用自定义 @Rule 来实现喜欢this one :

/**
* This rule registers Handlers for RxJava and RxAndroid to ensure that subscriptions
* always subscribeOn and observeOn Schedulers.trampoline().
* Warning, this rule will reset RxAndroidPlugins and RxJavaPlugins before and after each test so
* if the application code uses RxJava plugins this may affect the behaviour of the testing method.
*/
public class RxSchedulersOverrideRule implements TestRule {

private final Function<Callable<Scheduler>, Scheduler> mRxAndroidSchedulersHook =
new Function<Callable<Scheduler>, Scheduler>() {
@Override
public Scheduler apply(@NonNull Callable<Scheduler> schedulerCallable)
throws Exception {
return getScheduler();
}
};

private final Function<Scheduler, Scheduler> mRxJavaImmediateScheduler =
new Function<Scheduler, Scheduler>() {
@Override
public Scheduler apply(@NonNull Scheduler scheduler) throws Exception {
return getScheduler();
}
};

@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
RxAndroidPlugins.reset();
RxAndroidPlugins.setInitMainThreadSchedulerHandler(mRxAndroidSchedulersHook);

RxJavaPlugins.reset();
RxJavaPlugins.setIoSchedulerHandler(mRxJavaImmediateScheduler);
RxJavaPlugins.setNewThreadSchedulerHandler(mRxJavaImmediateScheduler);

base.evaluate();

RxAndroidPlugins.reset();
RxJavaPlugins.reset();
}
};
}

public Scheduler getScheduler() {
return Schedulers.trampoline();
}

}

使用此代码,您可以拦截所有调度程序并使所有内容在 trampoline() 上运行调度程序。

现在只需将以下 @Rule 添加到您的测试中:


public class MyTestClass {

@Rule
public final RxSchedulersOverrideRule mOverrideSchedulersRule = new RxSchedulersOverrideRule();

@Test
public void someTest() {
...
}
}

关于android - 测试特定用例时 TestScheduler 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49358096/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com