Model View Presenter presentation

DarxVal 2,007 views 19 slides Nov 06, 2015
Slide 1
Slide 1 of 19
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19

About This Presentation

Learn about the Model View Presenter pattern for Android


Slide Content

Model View Presenter Michael Cameron @Darxval

Getting Started - Name that Pattern!

Model - View - Controller

Pros and Cons? What are some pros and cons of MVC?

Name that Pattern!

Model - View - Presenter

Views Not to be confused with widget.view The view is a tattle tale Rule your views with an Iron Fist Tell it what to do Let the view tell you of everything that happens.

View Interfaces Don’t Trust any class, always have a contract Contract Details: View must let the presenter tell it what to do. View must let the presenter know of any events it has received

Presenter Tells the view and model objects what to do. Handles events

TaskIt! Add Tasks Have a list of Tasks Look at a task in detail

TaskIt MVP

TasksContract interface View { void setProgressIndicator ( boolean active ) ; void showTasks ( List<Task> tasks ) ; void showAddTask () ; void showTaskDetailUi ( String taskId ) ; } interface UserActionsListener { void loadTasks ( boolean forceUpdate ) ; void addNewTask () ; void openTaskDetails ( @NonNull Task requestedTask ) ; }

So… How do you test this??

Inversion of Control All you have to do is inject a mock instead of a concrete object to test parts of the app.

Inversion of Control public AddTaskPresenter ( @NonNull TasksRepository tasksRepository , @NonNull AddTaskContract.View addTaskView , @NonNull ImageFile imageFile ) { mTasksRepository = checkNotNull ( tasksRepository ) ; mAddTaskView = checkNotNull ( addTaskView ) ; addTaskView.setUserActionListener ( this ) ; mImageFile = imageFile ; }

Mock vs Concrete /** Prod Debug**/ public class Injection { public static ImageFile provideImageFile () { return new ImageFileImpl () ; } public static TasksRepository provideTasksRepository () { return TaskRepositories. getInMemoryRepoInstance ( new TasksServiceApiImpl ()) ; } } /** Mock Debug**/ public class Injection { public static ImageFile provideImageFile () { return new FakeImageFileImpl () ; } public static TasksRepository provideTasksRepository () { return TaskRepositories. getInMemoryRepoInstance ( new FakeTasksServiceApiImpl ()) ; } }

Unit Testing public class TaskDetailPresenterTest { public static final String INVALID_ID = "INVALID_ID" ; public static final String TITLE_TEST = "title" ; public static final String DESCRIPTION_TEST = "description" ; @Mock private TasksRepository mTasksRepository ; @Mock private TaskDetailContract.View mTaskDetailView ; /** * { @link ArgumentCaptor} is a powerful Mockito API to capture argument values and use them to * perform further actions or assertions on them. */ @Captor private ArgumentCaptor < TasksRepository.GetTaskCallback > mGetTaskCallbackCaptor ; private TaskDetailPresenter mTaskDetailsPresenter ; @Before public void setupNotesPresenter () { // Mockito has a very convenient way to inject mocks by using the @Mock annotation. To // inject the mocks in the test the initMocks method needs to be called. MockitoAnnotations. initMocks ( this ) ; // Get a reference to the class under test mTasksDetailsPresenter = new TaskDetailPresenter ( mTaskRepository , mTaskDetailView ) ; }

Espresso Test @RunWith ( AndroidJUnit4 . class ) @LargeTest public class TaskDetailScreenTest { private static String TASK_TITLE = "TaskIt" ; private static String TASK_DESCRIPTION = "Rocks" ; private static String TASK_IMAGE = "file:///android_asset/atsl-logo.png" ; /** * { @link Note} stub that is added to the fake service API layer. */ private static Task TASK = new Task ( TASK_TITLE , TASK_DESCRIPTION , TASK_IMAGE ) ; @Rule public ActivityTestRule < TaskDetailActivity > mTaskDetailActivityTestRule = new ActivityTestRule <>( TaskDetailActivity . class, true /* Initial touch mode */ , false /* Lazily launch activity */ ) ; @Test public void noteDetails_DisplayedInUi () throws Exception { // Check that the note title, description and image are displayed onView ( withId ( R.id.task _detail_title )). check ( matches ( withText ( TASK_TITLE ))) ; onView ( withId ( R.id. task_detail_description )). check ( matches ( withText ( TASK_DESCRIPTION ))) ; onView ( withId ( R.id. task_detail_image )). check ( matches ( allOf ( hasDrawable () , isDisplayed ()))) ; } }

Sources: MVP https://github.com/konmik/nucleus Google http://code-labs.io/codelabs/android-testing J. Amourette - https://plus.google.com/u/0/photos/102898026333733818285/albums/6081914916274644193/6081914917317951522?pid=6081914917317951522&oid=102898026333733818285 Thank You!