Friday, November 6, 2015

MVP: The Missing Link

I have been wanting to learn the Model View Presenter pattern for a while, and was super excited to get Michael Cameron to give a talk on it at GDG Boulder last night.

View Interface

I have this vague notion that MVP is good for JUnit testing, and I finally figured out why. The secret, the missing link, is View Interface, which is not a part of the MVP acronym. View Interface defines the contract between the view and the presenter, allowing you to mock one while testing the other.

With View Interface, you can compartmentalize your Android UI code into the view (typically a Fragment or Activity), which communicates with your presenter solely through the View Interface. This separation allows you to mock your View Interface with zero Android code, which means you can test your presenter with JUnit on the JVM.

Mocking via build flavors

Mocking is essential for hermetic testing, but people are often intimated by dependency injection frameworks like Dagger. If you prefer, you can provide mocks to your test using build flavors. An excellent technique!

Mockito

Mockito is a great mocking framework with a fluent API. One very nice feature is mocking via annotations. To use that, annotate the fields you want to mock with @Mock, and initialize them all with MockitoAnnotations.initMocks() in your @Before function.

@Mock
private MyThing myThing;

@Mock
private OtherThing otherThing;

@Before
public void setUp() throws Exception {
  MockitoAnnotations.initMocks(this);
}

This is equivalent to:

private MyThing myThing;
private OtherThing otherThing;

@Before public void setUp() throws Exception {
  myThing = Mockito.mock(MyThing.class);
  otherThing = Mockito.mock(OtherThing.class);
}

Slides: http://www.slideshare.net/DarxVal/model-view-presenter-presentation

Codelab

Google has published the excellent Android Testing Codelab going through an app with the MVP architecture. You can see JUnit and Espresso testing in action, mocks via build flavors, and various other techniques. Go check it out!

4 comments:

Inline coding questions will not be answsered. Instead, ask on StackOverflow and put the link in the comment.

  1. I been using MVP for android and it makes so easy testing and TDD, also it shows how bad is your architecture and help you clarify concepts like dependency injection. loving it!

    ReplyDelete
  2. MVP is great and finally there is an "official" example from Google!
    I am curious to see the talk "Android application architecture" at next Android Dev Summit https://plus.google.com/+AndroidDevelopers/posts/UdJFTiXx6Z9, I hope they'll show something related to MVVM pattern. I think that thanks to the data binding framework MVVM can be possibile on Android. In my opinion MVVM is even more testable than MVP, you can test the ViewModel easily because you don't need a mocked View (the ViewModel is not connected to the View).
    I am working on a simple MVVM implementation: https://github.com/fabioCollini/mv2m, it's still an early version so every feedback is welcome!

    ReplyDelete
  3. I am glad you brought up View Interfaces. Until now, I too was skeptical about the benefits of MVP for Unit Testing. But with View Initerfaces, I see the mocking benefit. I was wondering if you can expound on Dagger-less mocking via Build Variants in Android Studio? I am not too familiar with that technique until now...

    ReplyDelete
    Replies
    1. Please take a look at my primer on Daggerless mocking: https://gum.co/DaggerlessDITesting

      Delete