英文:
How to unit test Flowable.interval?
问题
以下是翻译好的部分:
"Here is the error that I get:"(这是我得到的错误消息:)
"Wanted but not invoked:"(期望但未调用:)
"However, there were other interactions with this mock:"(但是,模拟对象还有其他交互:)
"How I can solve this?"(我如何解决这个问题?)
希望这能帮助您解决问题。如果您需要更多信息,请随时提出。
英文:
I have the following code inside the presenter.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
public class SignUpPresenter implements Presenter {
private CompositeDisposable disposables;
private View view;
@Inject public SignUpPresenter() {
}
public void setView(View view) {
this.view = view;
}
public void redirectToLogInScreenAfterOneSecond() {
disposables = RxUtil.initDisposables(disposables);
view.displaySuccessMessage();
Disposable disposable = Flowable.interval(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> view.onRegistrationSuccessful(), view::handleError);
disposables.add(disposable);
}
@Override public void dispose() {
RxUtil.dispose(disposables);
}
public interface View extends Presenter.View {
void onRegistrationSuccessful();
void displaySuccessMessage();
}
}
<!-- end snippet -->
Now, I want to write unit test for that method.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
@RunWith(PowerMockRunner.class)
public class SignUpPresenterTest {
@Rule TrampolineSchedulerRule trampolineSchedulerRule = new TrampolineSchedulerRule();
@Mock SignUpPresenter.View view;
private SignUpPresenter presenter;
private TestScheduler testScheduler;
@Before public void setUp() {
testScheduler = new TestScheduler();
RxJavaPlugins.setComputationSchedulerHandler(scheduler -> testScheduler);
presenter = new SignUpPresenter();
presenter.setView(view);
}
@Test public void shouldDisplaySuccessMessage() {
testScheduler.advanceTimeTo(1, TimeUnit.SECONDS);
presenter.redirectToLogInScreenAfterOneSecond();
Mockito.verify(view).displaySuccessMessage();
Mockito.verify(view).onRegistrationSuccessful();
}
}
<!-- end snippet -->
Here is the error that I get:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
Wanted but not invoked:
view.onRegistrationSuccessful();
-> at com.test.presentation.signup.SignUpPresenterTest.shouldDisplaySuccessMessage(SignUpPresenterTest.java:36)
However, there were other interactions with this mock:
view.displaySuccessMessage();
-> at com.test.presentation.signup.SignUpPresenter.redirectToLogInScreenAfterOneSecond(SignUpPresenter.java:28)
Wanted but not invoked:
view.onRegistrationSuccessful();
-> at com.test.presentation.signup.SignUpPresenterTest.shouldDisplaySuccessMessage(SignUpPresenterTest.java:36)
However, there were other interactions with this mock:
view.displaySuccessMessage();
-> at com.test.presentation.signup.SignUpPresenter.redirectToLogInScreenAfterOneSecond(SignUpPresenter.java:28)
<!-- end snippet -->
How I can solve this?
答案1
得分: 2
以下是翻译好的部分:
@Test public void shouldDisplaySuccessMessage() {
presenter.redirectToLogInScreenAfterOneSecond();
testScheduler.advanceTimeTo(1, TimeUnit.SECONDS);
Mockito.verify(view).displaySuccessMessage();
Mockito.verify(view).onRegistrationSuccessful();
}
Also you don't need that many operators after interval but use the mainThread scheduler directly:
Disposable disposable = Flowable.interval(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.subscribe(aLong -> view.onRegistrationSuccessful(), view::handleError);
and replace the mainThread scheduler:
@Before public void setUp() {
testScheduler = new TestScheduler();
RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -> testScheduler);
presenter = new SignUpPresenter();
presenter.setView(view);
}
希望这能帮助你。如果有其他问题,请随时提出。
英文:
You have to move the time after the flow setup:
@Test public void shouldDisplaySuccessMessage() {
presenter.redirectToLogInScreenAfterOneSecond();
testScheduler.advanceTimeTo(1, TimeUnit.SECONDS);
Mockito.verify(view).displaySuccessMessage();
Mockito.verify(view).onRegistrationSuccessful();
}
Also you don't need that many operators after interval but use the mainThread scheduler directly:
Disposable disposable = Flowable.interval(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.subscribe(aLong -> view.onRegistrationSuccessful(), view::handleError);
and replace the mainThread scheduler:
@Before public void setUp() {
testScheduler = new TestScheduler();
RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -> testScheduler);
presenter = new SignUpPresenter();
presenter.setView(view);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论