Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instrumental Testing a view on MVP

I'm developing an Android App with an MVP architecture, I've been able to test both Presenter and Model classes, but now I'm trying to test the View methods. For instance, I have the following view:

public interface SplashView extends BaseMVPView {

    void initPresenter();

    void navigateToHome();

    void onError(ApiError apiError);
}

Which is implemented by an Activity.

public class SplashActivity extends BaseActivity implements SplashView {

    // MVP Presenter
    private SplashPresenter splashPresenter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initPresenter();
    }

    @Override
    public int getLayoutId() {
        return R.layout.activity_splash;
    }

    @Override
    public void destroy() {
        if(splashPresenter != null) {
            splashPresenter.onDestroy();
            splashPresenter = null;
        }
    }

    @Override
    public void initPresenter() {
        if(splashPresenter == null) {
            splashPresenter = new SplashPresenterImpl(this, ApiClient.getService());
            sync();
        }
    }

    @Override
    public void navigateToHome() {
        NavigationUtils.navigateToActivity(this, MainActivity.class, true);
    }

    @Override
    public void onError(ApiError apiError) {
        DialogUtils.showOKCancelDialog(...);
    }

    private void sync() {
        if(splashPresenter != null) {
            splashPresenter.sync();
        }
    }
}

As you can see, when the activity is created it initialized the presenter and calls a method that will get some data from the API. Once the API call is done, the presenter will call either the navigateToHome or the onError methods. So I would like to test this process for both cases. I guess this must be an instrumental test but I don't know how to deal with this cases, and how to call the methods.

Thanks a lot

like image 448
FVod Avatar asked Oct 30 '22 18:10

FVod


1 Answers

First of all I suggest to mix up your MVP architecture with some Dagger taste for dependency injection which really helps with testing and Mocking. You can learn more using the sample I have published on my Github which also contains different type of tests:

http://github.com/mmirhoseini/fyber_mobile_offers

By the way, in this type of development you have to Mock your SplashPresenter and insert it instead of the real one to let you change the real presenter with a mocked presenter that do what you want.

For doing this you have to extend your Activity and override initPresenter method:

class MockSplashActivity extends SplashActivity {
    @Override
    public void initPresenter() {
        if (splashPresenter == null) {
            splashPresenter = new MockSplashPresenterImpl(this, ApiClient.getService());
            sync();
        }
    }
}

and also extend your presenter and change the method you want to act the way you want in testing (I think you want to do something with sync method):

class MockSplashPresenterImpl extends SplashPresenterImpl {
    public MockSplashPresenterImpl(SplashActivity splashActivity, Object service) {
        super(splashActivity, service);
    }

    @Override
    public void sync() {
        splashActivity.doSomethingYouWant();
    }
}

I hope it helps :)

like image 82
Mohsen Mirhoseini Avatar answered Nov 09 '22 13:11

Mohsen Mirhoseini