简体   繁体   English

如何在Android(MVP)上测试主持人?

[英]How to test presenter on android (MVP)?

I've never create unit testing before. 我以前从未创建过单元测试。 I'm planning to create UI test & Unit test for my presenter & datasource. 我打算为演示者和数据源创建UI测试和单元测试。 I use Retrofit, RxJava, and Dagger in my apps. 我在应用程序中使用Retrofit,RxJava和Dagger。

Here's what i've tried so far 到目前为止,这是我尝试过的

DataSource (My Datasource is coming from API) 数据源(我的数据源来自API)

public class DataSource implements DataSourceContract {

    private static DataSource dataSource;

    @Inject
    SharedPreferences sharedPreferences;
    @Inject
    NewsService newsService;

    private DataSource(Context context) {
        DaggerAppComponent.builder()
                .networkModule(new NetworkModule(API_URL))
                .appModule(new AppModule(context.getApplicationContext()))
                .preferencesModule(new PreferencesModule())
                .build()
                .inject(this);
    }

    public static synchronized DataSource getInstance(Context context) {
        if(dataSource == null) {
            dataSource = new DataSource(context);
        }

        return dataSource;
    }

    public String parseError(Throwable e) {
        if(e instanceof SocketTimeoutException) {
            return ERROR_TIMEOUT;
        }
        else if(e instanceof SocketException) {
            return ERROR_NO_CONNECTION;
        }
        else {
            return ERROR_SERVER;
        }
    }

    @Override
    public DisposableObserver<NewsResponse> getNews(final Callback<NewsResponse> callback) {
        return newsService.getNews()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableObserver<NewsResponse>() {
                    @Override
                    public void onNext(NewsResponse value) {
                        callback.onSuccess(value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        callback.onFailure(e);
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

Presenter 主持人

public class MainPresenter implements MainContract.Presenter {
    private MainContract.View view;
    private DataSource dataSource;
    private Disposable dispossable;

    public MainPresenter(MainContract.View view, DataSource dataSource) {
        this.view = view;
        this.dataSource = dataSource;
    }

    @Override
    public void onStart() {
        getNews();
    }

    @Override
    public void onStop() {
        if(dispossable != null && !dispossable.isDisposed()) {
            dispossable.dispose();
        }
    }

    @Override
    public void getNews() {
        view.setLoading(true);

        dispossable = dataSource.getNews(new DataSourceContract.Callback<NewsResponse>() {
            @Override
            public void onSuccess(NewsResponse responseData) {
                try {
                    switch (responseData.getStatus()) {
                        case API_SUCCESS:
                            view.setLoading(false);
                            view.getNewsSuccess(responseData.getArticles());
                            break;
                        default:
                            view.setLoading(false);
                            view.getNewsFailed(responseData.getStatus());
                            break;

                    }
                }
                catch (Exception e) {
                    view.setLoading(false);
                    view.getNewsFailed(ERROR_SERVER);
                }
            }

            @Override
            public void onFailure(Throwable e) {
                view.setLoading(false);
                view.isNetworkFailed(dataSource.parseError(e), false);
            }
        });
    }
}

And this is the test of my presenter 这是我的主持人的考验

public class MainPresenterTest {
    @Mock
    DataSource dataSource;

    @Mock
    MainContract.View view;

    MainContract.Presenter presenter;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        presenter = new MainPresenter(view, dataSource);
    }

    @Test
    public void getNews() throws Exception {
        List<Article> articleList = new ArrayList<>();
        presenter.getNews();
        Mockito.verify(view, Mockito.only()).getNewsSuccess(articleList);
    }
}

But there is error when I run the test 但是运行测试时会出错

Wanted but not invoked:
view.getNewsSuccess([]);
-> at com.java.mvp.view.main.MainPresenterTest.getNews(MainPresenterTest.java:37)

I have no problem running this apps on the device, but I can't make it work on testing 我在设备上运行此应用程序没有问题,但是我无法使其在测试中正常工作

Any idea how to fix this presenter test? 任何想法如何解决此演示者测试? Am I doing it right? 我做对了吗?

And how do I test my datasource? 以及如何测试我的数据源? I have no idea how to test this one 我不知道该如何测试

Thank you 谢谢

You have to mock also : 您还必须嘲笑:

dataSource.getNews() using Mockito when : 在以下情况下使用Mockito的dataSource.getNews():

eg 例如

when(dataSource.getNews()).thenReturn(new SuccessCallback());

So you have to lead your test code into the success callback and check there what methods are called. 因此,您必须将测试代码引入成功回调中,并检查其中调用了哪些方法。 The same goes with the eroor case. 肮脏的情况也是如此。

Keep things simple. 保持简单。 You are testing your presenter, not the data source. 您正在测试演示者,而不是数据源。 Add new methods to your presenter for the success and error responses. 向您的演示者添加新方法,以获取成功和错误响应。 Then add two tests: one for the success and one for the error. 然后添加两个测试:一个测试成功,另一个测试错误。

    @Override
    public void getNews() {
        view.setLoading(true);

        dispossable = dataSource.getNews(new DataSourceContract.Callback<NewsResponse>() {
            @Override
            public void onSuccess(NewsResponse responseData) {
                onSuccessNewsResponse(responseData);
            }

            @Override
            public void onFailure(Throwable e) {
                onErrorNewsResponse(e);
            }
        });
    }

Add @VisibleForTesting annotation to the new methods. @VisibleForTesting批注添加到新方法。

Success test: 成功测试:

@Test
public void getNewsSuccess() {
    presenter.onSuccessNewsResponse(your_response); 
    Mockito.verify(...);
}

Error test: 错误测试:

@Test
public void getNewsError() {
    presenter.onErrorNewsResponse(your_error);
    Mockito.verify(...);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM