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); }
Model View Presenter for Android by @Darxval at @gdgboulder #Sketchnotes pic.twitter.com/T7QX0FTPzQ
— Chiu-Ki Chan (@chiuki) November 6, 2015
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!
Inline coding questions will not be answsered. Instead, ask on StackOverflow and put the link in the comment.
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!
ReplyDeleteMVP is great and finally there is an "official" example from Google!
ReplyDeleteI 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!
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...
ReplyDeletePlease take a look at my primer on Daggerless mocking: https://gum.co/DaggerlessDITesting
Delete