Slide 1

Slide 1 text

Testing in MVVM with clean Architecture - Sujata Gopal Swamy - Sr Android Developer @ Airfi Aviation Solutions

Slide 2

Slide 2 text

Organization Architecture

Slide 3

Slide 3 text

Features of MVVM architecture ● Separation of concerns ● Separation of UI from backend logic ● Its target is to achieve the following principle “Keeping UI code simple and free of app logic in order to make it easier to manage”.

Slide 4

Slide 4 text

MVVM architecture

Slide 5

Slide 5 text

● Your code is even more easily testable than with plain MVVM. Why MVVM with Clean Architecture? ● Your code is further decoupled (the biggest advantage.) ● The package structure is even easier to navigate. ● The project is even easier to maintain. ● Your team can add new features even more quickly.

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Pros of using a Clean Architecture ● It's easier to maintain the project and add new features ● Code is more decoupled and testable ● You can replace the framework and presentation layers and port your app on a different platform

Slide 8

Slide 8 text

Cons of Using Clean Architecture ● You’ll have to learn and understand clean architecture to work on the project ● You’ll have to write more code but it pays off

Slide 9

Slide 9 text

Types of Testing

Slide 10

Slide 10 text

Layers to test in clean architecture 1. Activity / Fragment 2. Viewmodel 3. Use cases 4. Repository 5. Datasource

Slide 11

Slide 11 text

Test Doubles ● Mock ● Fake ● Stub

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

UI or Espresso Test @Test public void test() { onView(withId(R.id.spinner)).perform(click()); onData(allOf(is(instanceOf(String.class)), is("Author1"))) .perform(click()); onView(withId(R.id.spinner)) .check(matches(withSpinnerText("Author1"))); } @Rule public ActivityTestRule activityRule = new ActivityTestRule<>(BookActivity.class);

Slide 14

Slide 14 text

Example of writing a unit test for a View model @Before public void setupAddEditTaskViewModel() { MockitoAnnotations.initMocks(this); bookViewModel = spy(new BookViewModel(application,mAuthorNameUseCase,mBookUseCase)); } @Rule public InstantTaskExecutorRule instantExecutorRule = new InstantTaskExecutorRule();

Slide 15

Slide 15 text

Continued.. example. @Test Public void testauthorList() { } MutableLiveData> listMutableLiveData = new MutableLiveData<>(); List stringList = new ArrayList<>(); stringList.add("author1"); listMutableLiveData.setValue(stringList); verify(mAuthorNameUseCase).getAuthorNamesList(mGetAuthorNameArgumentCaptor.capture()); mGetAuthorNameArgumentCaptor.getValue().onAuthorNameLoaded(listMutableLiveData); assertThat(bookViewModel.getAuthorNameListLiveData() .getValue().size(), is(equalTo(1)));

Slide 16

Slide 16 text

Example of writing unit test for a datasource @Test public void testSalesData() { } List bookList = new ArrayList<>(); BookDataSource dataSource = Mockito.mock(BookDataSource.class); Mockito.doReturn(Observable.just(bookList)).when(dataSource) .getBookNameList("Author1"); dataSource.getBookNameList("Author1") .test() .assertValues(bookList) .dispose();

Slide 17

Slide 17 text

Example of writing unit test for repository @Test public void testAuthorNamesListCallback() { } MutableLiveData> listMutableLiveData = new MutableLiveData<>(); List stringList = new ArrayList<>(); stringList.add("Author1"); listMutableLiveData.setValue(stringList); bookRepository.getAuthorNameList(mAuthorNameCallBack); verify(bookDataSource).getAuthorNameList(mAuthorNameCallbackCaptor.capture()); mAuthorNameCallbackCaptor.getValue().onAuthorNameLoaded(listMutableLiveData); verify(bookDataSource) .getAuthorNameList(ArgumentMatchers.any(BookDataSource.GetAuthorNameCallback.class));

Slide 18

Slide 18 text

Writing a unit test case for Use-Case @Test public void testUseCaseCallBack() { } MutableLiveData> listMutableLiveData = new MutableLiveData<>(); List bookdataList = new ArrayList<>(); bookdataList.add("Author2"); listMutableLiveData.setValue(bookdataList); authorNameUseCase.getAuthorNamesList(mAuthorNameCallBack); // passing mocked object verify(authorNameUseCase).getAuthorNamesList( mAuthorUseCaseCallbackCaptor.capture()); mAuthorUseCaseCallbackCaptor.getValue().onAuthorNameLoaded(listMutableLiveData); verify(authorNameUseCase) .getAuthorNamesList(any(BookRepositoryContract.GetAuthorNameCallback.class));

Slide 19

Slide 19 text

Key takeaways Overview on MVVM architecture Overview on clean architecture Overview on Unit & UI Testing in android with clean architecture

Slide 20

Slide 20 text

Useful links and resources for mvvm with clean architecture https://www.raywenderlich.com/3595916-clean-architecture-tutorial-for-androi d-getting-started#toc-anchor-026 https://five.agency/android-architecture-part-5-test-clean-architecture/ https://www.youtube.com/watch?v=VJi2vmaQe6w&t=1997s

Slide 21

Slide 21 text

Thank you @sw_swamy Please find below github link for the demo project https://github.com/SujataSwamy/testing_in_mvvm_with_clean_architecture https://www.linkedin.com/in/sujata-swamy/