开发者社区 问答 正文

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

我在演示者内部有以下代码。


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();
  }
} 

现在,我想为该方法编写单元测试。

@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();
  }
} 

这是我得到的错误:

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) 

我该如何解决?

展开
收起
Puppet 2020-01-06 22:17:32 1021 分享 版权
1 条回答
写回答
取消 提交回答
  • 流程设置后,您必须移动时间:

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

    另外,在间隔之后您不需要那么多运算符,而是直接使用mainThread调度程序:

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

    并替换mainThread调度程序:

    @Before public void setUp() {
        testScheduler = new TestScheduler();
        RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -> testScheduler);
        presenter = new SignUpPresenter();
        presenter.setView(view);
    }
    
    2020-01-06 22:18:57
    赞同 展开评论
问答分类:
问答地址: