How to unit-test a presenter in a MVP?

In a unit test perspective: should the view specify presenter or the other way around in GWT MVP?

  • In tutorials on GWT Google uses to different approaches to do MVP, either the View specifies the Presenter or the Presenter specifies the View. The first one is used when using Activities and Places. This post touches on this subject: http://stackoverflow.com/questions/3309029/mvp-should-the-view-implement-a-presenters-interface-or-vice-versa However I would like to know which alternative you think is best when it comes to unit testing of the presenter and the view? Or will both work equally well?

  • Answer:

    The idea behind unit testing of presenter is to mock the view, and write several assertions against state of this mocked view, which would be represented visually in the real life app. Thanks to such an approach there is no need for running full GWTTestCase, which takes a lot of time and should be rather put in the category of integration testing, not unit testing. If you would try both MVP approaches, the unit tests could look like: MVP 1: @Test public void shouldAddContactOnAddContactClicked() { // given ContactsPresenter.Display display = mock(ContactsPresenter.Display.class); MockButton addButton = new MockButton(); given(display.getAddButton()).willReturn(addButton); ContactsDisplay.Presenter presenter = new ContactsPresenter(); presenter.bindView(display); presenter.setContacts(new ArrayList<Contact>()); // when addButton.click(); // then verify(display).addContact(any()); assertThat(presenter.getContacts().size(), is(1)); } Where the MockButton is something I described here: http://stackoverflow.com/questions/3417551/comprehensive-pros-cons-of-mocking-frameworks-for-gwt/3428673#3428673 Although possible, it is not really convenient to mock things this way. The MVP2 approach seems to perform better: @Test public void shouldAddContactOnAddContactClicked() { // given ContactsView view = mock(ContactsView.class); ContactsView.Presenter presenter = new ContactsPresenter(); presenter.bindView(view); // assuming that presenter will call view.setPresenter(this) presenter.setContacts(new ArrayList<Contact>()); // when presenter.onAddContactClicked(); // then verify(view).addContact(any()); assertThat(presenter.getContacts().size(), is(1)); } Another reason for using the second approach is the problem in MVP1 with declaring elements of the display, which would trigger different events (e.g. ClickEvent, FocusEvent). MVP2 also makes things easier when it comes to UiBinder.

Pich at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

Avoid using HasXxxHandlers, i.e. use the approach from the http://code.google.com/webtoolkit/articles/mvp-architecture-2.html article where each peer has a reference to the other. HasXxxHandlers are far too complicated to mock, particularly when using mocking libraries such as Mockito or EasyMock. For best testability, you'd inject the view into the presenter and the presenter would then call a setPresenter or setDelegate method of the view (that way, you can unit test that you correctly call that method, at the right time). When using Activities, where your activity is a presenter, you'll likely call view.setPresenter(this) in start and view.setPresenter(null) in onStop and onCancel; that way you can have a singleton view shared with several presenters (though no more than a single one at a time, obviously).

Thomas Broyer

Unit-test-wise, it really doesn't matter. If you design it right, it is just a matter of where you need a stub (or mock) injected. The unit test should not be allowed to dictate design decisions. However, a unit-test will often indicate if a design is wrong (such as missing injection etc.)

Morten

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.