如何在android(MVP)上测试演示者?

时间:2018-02-13 11:41:37

标签: android testing mvp

我以前从未创建过单元测试。我打算创建UI测试&我的演示者的单元测试&数据源。我在我的应用程序中使用了Retrofit,RxJava和Dagger。

这是我到目前为止所尝试的内容

DataSource(我的数据源来自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() {

                    }
                });
    }
}

演示

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

这是我演示者的测试

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

但是当我运行测试时出现错误

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

我在设备上运行此应用程序没有问题,但我无法使其在测试中运行

知道如何修复此演示者测试吗?我做得对吗?

我如何测试我的数据源?我不知道如何测试这个

谢谢

2 个答案:

答案 0 :(得分:1)

你还必须嘲笑:

dataSource.getNews()使用Mockito时:

e.g。

myWebView.loadUrl("http://www.molssoft.lv/akmens/");

因此,您必须将测试代码引入成功回调,并检查调用哪些方法。 eroor案例也是如此。

答案 1 :(得分:1)

保持简单。您正在测试演示者,而不是数据源。向演示者添加新方法以获取成功和错误响应。然后添加两个测试:一个用于成功,一个用于错误。

<!doctype html>
<html>
    <head>

    </head>
    <body>
    <h4>These are the current items in your Basket</h4>



    <form method="POST"> 
        {% csrf_token %}
        {% for cart in  my_carts_current_entries %}
        {{ cart.quantity }} x {{ cart.product }} <br>
        {% endfor %}
        <input type="hidden" name='entry_quantity' value='{{ cart.quantity }}'>
        <button>Add to Basket</button>
    </form>

    </body>
</html>

@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); } }); } 注释添加到新方法中。

成功测试:

@VisibleForTesting

错误测试:

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