mardi 13 février 2018

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. I use Retrofit, RxJava, and Dagger in my apps.

Here's what i've tried so far

DataSource (My Datasource is coming from 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

Aucun commentaire:

Enregistrer un commentaire