如何对Flowable.interval进行单元测试?

huangapple go评论101阅读模式
英文:

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 -->

  1. public class SignUpPresenter implements Presenter {
  2. private CompositeDisposable disposables;
  3. private View view;
  4. @Inject public SignUpPresenter() {
  5. }
  6. public void setView(View view) {
  7. this.view = view;
  8. }
  9. public void redirectToLogInScreenAfterOneSecond() {
  10. disposables = RxUtil.initDisposables(disposables);
  11. view.displaySuccessMessage();
  12. Disposable disposable = Flowable.interval(1, TimeUnit.SECONDS)
  13. .subscribeOn(Schedulers.io())
  14. .observeOn(AndroidSchedulers.mainThread())
  15. .subscribe(aLong -&gt; view.onRegistrationSuccessful(), view::handleError);
  16. disposables.add(disposable);
  17. }
  18. @Override public void dispose() {
  19. RxUtil.dispose(disposables);
  20. }
  21. public interface View extends Presenter.View {
  22. void onRegistrationSuccessful();
  23. void displaySuccessMessage();
  24. }
  25. }

<!-- end snippet -->

Now, I want to write unit test for that method.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

  1. @RunWith(PowerMockRunner.class)
  2. public class SignUpPresenterTest {
  3. @Rule TrampolineSchedulerRule trampolineSchedulerRule = new TrampolineSchedulerRule();
  4. @Mock SignUpPresenter.View view;
  5. private SignUpPresenter presenter;
  6. private TestScheduler testScheduler;
  7. @Before public void setUp() {
  8. testScheduler = new TestScheduler();
  9. RxJavaPlugins.setComputationSchedulerHandler(scheduler -&gt; testScheduler);
  10. presenter = new SignUpPresenter();
  11. presenter.setView(view);
  12. }
  13. @Test public void shouldDisplaySuccessMessage() {
  14. testScheduler.advanceTimeTo(1, TimeUnit.SECONDS);
  15. presenter.redirectToLogInScreenAfterOneSecond();
  16. Mockito.verify(view).displaySuccessMessage();
  17. Mockito.verify(view).onRegistrationSuccessful();
  18. }
  19. }

<!-- end snippet -->

Here is the error that I get:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

  1. Wanted but not invoked:
  2. view.onRegistrationSuccessful();
  3. -&gt; at com.test.presentation.signup.SignUpPresenterTest.shouldDisplaySuccessMessage(SignUpPresenterTest.java:36)
  4. However, there were other interactions with this mock:
  5. view.displaySuccessMessage();
  6. -&gt; at com.test.presentation.signup.SignUpPresenter.redirectToLogInScreenAfterOneSecond(SignUpPresenter.java:28)
  7. Wanted but not invoked:
  8. view.onRegistrationSuccessful();
  9. -&gt; at com.test.presentation.signup.SignUpPresenterTest.shouldDisplaySuccessMessage(SignUpPresenterTest.java:36)
  10. However, there were other interactions with this mock:
  11. view.displaySuccessMessage();
  12. -&gt; at com.test.presentation.signup.SignUpPresenter.redirectToLogInScreenAfterOneSecond(SignUpPresenter.java:28)

<!-- end snippet -->
How I can solve this?

答案1

得分: 2

以下是翻译好的部分:

  1. @Test public void shouldDisplaySuccessMessage() {
  2. presenter.redirectToLogInScreenAfterOneSecond();
  3. testScheduler.advanceTimeTo(1, TimeUnit.SECONDS);
  4. Mockito.verify(view).displaySuccessMessage();
  5. Mockito.verify(view).onRegistrationSuccessful();
  6. }
  7. Also you don't need that many operators after interval but use the mainThread scheduler directly:
  8. Disposable disposable = Flowable.interval(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
  9. .subscribe(aLong -> view.onRegistrationSuccessful(), view::handleError);
  10. and replace the mainThread scheduler:
  11. @Before public void setUp() {
  12. testScheduler = new TestScheduler();
  13. RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -> testScheduler);
  14. presenter = new SignUpPresenter();
  15. presenter.setView(view);
  16. }

希望这能帮助你。如果有其他问题,请随时提出。

英文:

You have to move the time after the flow setup:

  1. @Test public void shouldDisplaySuccessMessage() {
  2. presenter.redirectToLogInScreenAfterOneSecond();
  3. testScheduler.advanceTimeTo(1, TimeUnit.SECONDS);
  4. Mockito.verify(view).displaySuccessMessage();
  5. Mockito.verify(view).onRegistrationSuccessful();
  6. }

Also you don't need that many operators after interval but use the mainThread scheduler directly:

  1. Disposable disposable = Flowable.interval(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
  2. .subscribe(aLong -&gt; view.onRegistrationSuccessful(), view::handleError);

and replace the mainThread scheduler:

  1. @Before public void setUp() {
  2. testScheduler = new TestScheduler();
  3. RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -&gt; testScheduler);
  4. presenter = new SignUpPresenter();
  5. presenter.setView(view);
  6. }

huangapple
  • 本文由 发表于 2020年1月6日 16:19:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/59608753.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定