在Android中的MVP Presenter中对RxJava进行单元测试 [英] Unit testing RxJava in MVP presenter in android

查看:230
本文介绍了在Android中的MVP Presenter中对RxJava进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是TDD的新手.同样是MVP和Rxjava的新功能.我只是深入研究,这是值得的.但是我停留在测试部分.我了解单元测试的基础.一开始对我来说有点困难.但是我被困在这里,那么如何测试演示者呢?

I am new to TDD. Also new to MVP and Rxjava. I just dive into it and It is worth it. But I stuck at the testing part. I understand the basis of unit testing. It is a little bit difficult for me in beginning. But I stuck here and So how can test the presenter?

这是Presenter类-

Here is the Presenter class -

public class NewsPresenter {

private final RxjavaService service;
private final MainView view;
private CompositeSubscription subscriptions;

public NewsPresenter(RxjavaService service, MainView view) {
    this.service = service;
    this.view = view;
    subscriptions = new CompositeSubscription();
}

public void getNewsList(String urlQ){
    view.showWait();

    Subscription subscription = service.getNews(urlQ ,new RxjavaService.GetNewsCallback() {
        @Override
        public void onSuccess(Articles articles) {
            view.removeWait();
            view.getNewsListSuccess(articles);
        }

        @Override
        public void onError(NetworkError networkError) {
            view.removeWait();
            view.onFailure(networkError.getAppErrorMessage());
            Log.i("huh",networkError.getMessage());
        }
    });

    subscriptions.add(subscription);
}

public void onStop(){
    subscriptions.unsubscribe();
}

}

这是视图界面-

public interface MainView {

void showWait();

void removeWait();

void onFailure(String appErrorMessage);

void getNewsListSuccess(Articles articles);

}

这是RxJavaService类-

Here is the RxJavaService class -

public class RxjavaService {

private final NewsRestService newsRestService;

public RxjavaService(NewsRestService newsRestService) {
    this.newsRestService = newsRestService;
}


public interface GetNewsCallback {
    void onSuccess(Articles articles);

    void onError(NetworkError networkError);
}


public Subscription getNews(String q, final GetNewsCallback getNewsCallback) {
    Log.i("stuck","service called");
    return newsRestService.getNewsBySearch(q,"8dca7dea475e41e49518b2c61131e118",100)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .onErrorResumeNext(new Func1<Throwable, Observable<? extends Articles>>() {
                @Override
                public Observable<? extends Articles> call(Throwable throwable) {
                    return Observable.error(throwable);
                }
            })
            .subscribe(new Subscriber<Articles>() {
                @Override
                public void onCompleted() {
                    Log.i("stuck","complete");
                }

                @Override
                public void onError(Throwable e) {
                    getNewsCallback.onError(new NetworkError(e));
                    Log.i("stuck",e.getMessage());
                }

                @Override
                public void onNext(Articles articles) {
                    getNewsCallback.onSuccess(articles);
                    Log.i("stuck","Onnext");
                }
            });
}

}

这是我被困的Test类-

Here is the Test class where I am stuck-

@RunWith(MockitoJUnitRunner.class)

public class NewsListTest {

private NewsPresenter newsPresenter;

@Mock
private RxjavaService rxjavaService;
@Mock
private MainView mainView;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);

    newsPresenter = new NewsPresenter(rxjavaService,mainView);
}

@After
public void tearDown() throws Exception {
    mainView = null;
    newsPresenter.onStop();
}

@Test
public void Testing_The_Result() {

}

}

推荐答案

第一件事

  1. 如果您要使用TDD,就永远不会遇到您所描述的情况.在TDD中,您以失败的测试开始,然后立即编写实现.因此,您的问题更多的是测试,然后是TDD.
  2. 我建议您切换到RxJava2,因为RxJava1将于3月31日到期.
  3. 让我感到奇怪的是,RxJavaService将API从发布/订阅更改为回调.为什么不一直使用rx API进行演示?
  1. If you're into TDD, you'd never get into the situation you described. In TDD you start with a failing test, and just then go write the implementation. So your question is much more about testing then TDD.
  2. I would recommend switching to RxJava2, as RxJava1 reaches End Of Life on March 31.
  3. Look strange to me that RxJavaService changes the API from publish/subscribe to callbacks. Why not stick with rx API all the way to presenter?

使用模拟的RxJavaService进行测试

如果您要使用测试中的设置完成编写测试的过程,它将看起来像这样:

Test with mocked RxJavaService

If you'd like to finish writing the test with the setup you have in the test, it would look something like this:

@Test
public void Testing_The_Result() {
    final RxjavaService.GetNewsCallback[] callback = new RxjavaService.GetNewsCallback[1];
    Mockito.when(rxjavaService.getNews(ArgumentMatchers.anyString(), ArgumentMatchers.any(RxjavaService.GetNewsCallback.class))).thenAnswer(new Answer<Subscription>() {
        public Subscription answer(InvocationOnMock invocationOnMock) {
            callback[0] = invocationOnMock.getArgument(1);
            return mock(Subscription.class);
        }
    });
    newsPresenter.getNewsList("some url");
    Articles articles = new Articles();

    callback[0].onSuccess(articles);

    verify(mainView).removeWait();
    verify(mainView).getNewsListSuccess(articles);
}

您可以通过不使用Mockito模拟RxJavaService来摆脱丑陋的代码,而滚动自己的手写模拟,它将存储回调并将其提供给测试.

You can get rid of the ugly code by not using Mockito to mock RxJavaService, but rather roll you own hand-written mock, which would store the callback and provide it to the test.

但是,我建议使用另一种方法.

However, I'd recommend a different approach.

如果我们只嘲笑NewsRestService

@RunWith(MockitoJUnitRunner.class)
public class NewsList2Test {

    private NewsPresenter newsPresenter;

    @Mock
    private MainView mainView;
    @Mock
    private NewsRestService newsRestService;

    @Before
    public void setUp() {
        newsPresenter = new NewsPresenter(new RxjavaService(newsRestService), mainView);
    }

    @Test
    public void show_success_in_view_when_there_are_articles() {
        when(newsRestService.getNewsBySearch(eq("some url"), anyString(), anyInt()))
                .thenReturn(Observable.just(new Articles()));

        newsPresenter.getNewsList("some url");

        verify(mainView).removeWait();
        verify(mainView).getNewsListSuccess(any(Articles.class));
    }

}

这篇关于在Android中的MVP Presenter中对RxJava进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆