Testing the ViewModels in Open Event Organizer App

In Open Event Organizer Android App we follow Test Driven Development Approach which means the features added in the app are tested thoroughly by unit tests. More tests would ensure better code coverage and fewer bugs. This blog explains how to write tests for Viewmodel class in MVVM architecture. Specifications We will use JUnit4 to write unit tests and Mockito for creating mocks. The OrdersViewModel class returns the list of Order objects to the Fragment class. The objects are requested from OrderRepository class which fetches them from Network and Database. We will create a mock of OrderRepository class since it is out of context and contain logic that doesn’t depend on Orders Respository. Below is the getOrders method that we will test.  public LiveData<List<Order>> getOrders(long id, boolean reload) { if (ordersLiveData.getValue() != null && !reload) return ordersLiveData; compositeDisposable.add(orderRepository.getOrders(id, reload) .compose(dispose(compositeDisposable)) .doOnSubscribe(disposable -> progress.setValue(true)) .doFinally(() -> progress.setValue(false)) .toList() .subscribe(ordersLiveData::setValue, throwable -> error.setValue(ErrorUtils.getMessage(throwable).toString()))); return ordersLiveData; } We will be using InstantTaskExecutorRule() which is a JUnit Test Rule that swaps the background executor used by the Architecture Components with a different one which executes each task synchronously. We will use setUp() method to load the RxJavaPlugins, RxAndroid plugins and reset them in tearDown method which will ensure each test runs independently from the other and avoid memory leaks. After doing this initialization and basic setup for tests we can begin code the method shouldLoadOrdersSuccessfuly() to test the getOrders method present in ViewModel class. Let’s see the step by step approach. Use Mockito.when to return Observables one by one from ORDERS_LIST whenever the method getOrders of the mock orderRepository is called. We will use Mockito.InOrder and pass orders, orderRepository and progress to check if they are called in a particular order. We will use .observeForever method to observe on LiveData objects and add a ArrayList on change. Finally, we will test and verify if the methods are called in order. @Test public void shouldLoadOrdersSuccessfully() { when(orderRepository.getOrders(EVENT_ID, false)) .thenReturn(Observable.fromIterable(ORDERS_LIST)); InOrder inOrder = Mockito.inOrder(orders, orderRepository, progress); ordersViewModel.getProgress().observeForever(progress); orders.onChanged(new ArrayList<>()); ordersViewModel.getOrders(EVENT_ID, false); inOrder.verify(orders).onChanged(new ArrayList<>()); inOrder.verify(orderRepository).getOrders(EVENT_ID, false); inOrder.verify(progress).onChanged(true); inOrder.verify(progress).onChanged(false); } Similar approach can be followed for writing tests to check other behaviour of the ViewModel. References Official Documentation for testing. https://developer.android.com/reference/android/arch/core/executor/testing/InstantTaskExecutorRule Official Documentation for JUnit.  https://junit.org/junit4/ Official documentation for Mockito.  http://site.mockito.org/ Open Event Organizer App codebase.  https://github.com/fossasia/open-event-orga-app

Continue ReadingTesting the ViewModels in Open Event Organizer App

Implement Tests for Feedback List in Open Event Orga App

In the Open Event Orga App test have been written for all the presenters and viewmodel classes to ensure that the implemented functionalities work well. In the following blog post I have discussed one particular test which I implemented which is the FeedbackList Presenter Test. Implementation Instantiation of the variables. @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock public FeedbackListView feedbackListView; @Mock public FeedbackRepository feedbackRepository; We should first know the meaning of the Annotations being used: @Rule : It tells mockito to create the mocks based on the @Mock annotation. This annotation always needs to be used. @Mock: It tells Mockito to mock the FeedbackListView interface and FeedbackRepository class. Here we are mocking 3 classes namely: MockitoRule, FeedbackListView, FeedbackRepository. Before moving forward we first need to understand the meaning of Mock. A mock object is a dummy implementation for an interface or a class in which you define the output of certain method calls. Mock objects are configured to perform a certain behavior during a test. They typically record the interaction with the system and tests can validate that.   private static final List<Feedback> FEEDBACKS = Arrays.asList(   Feedback.builder().id(2L).comment("Amazing!").build(),   Feedback.builder().id(3L).comment("Awesome!").build(),   Feedback.builder().id(4L).comment("Poor!").build() ); The list of feedbacks is populated with demo values which can be used for testing purpose later. 2) The @Before annotation is applied before the set up. Before any tests are created, the setUp( ) is executed. A feedbackListPresenter object is created and the required parameters are passed. The RxJava Plugin’s setIoSchedulerHandler, setComputationSchedulerHandler and setInitmainThreadSchedulerHandler use the Scheduler.Trampoline( ) .  It lets the internal call Observable call to end before asserting the result. setIOSchedulerHandler( ) -> It basically is a type of Scheduler which handles the Input and Output of the RxJava code. setComputationSchedulerHandler( ) -> It is another Scheduler which handles the computations which are carried out during call to RxJava methods. setInitMainThreadSchedulerHandler( ) -> It is called to notify the Scheduler that the IO operations would be carried out on the main thread. @Before public void setUp() {   feedbackListPresenter = new FeedbackListPresenter(feedbackRepository);   feedbackListPresenter.attach(ID, feedbackListView);   RxJavaPlugins.setIoSchedulerHandler(scheduler -> Schedulers.trampoline());   RxJavaPlugins.setComputationSchedulerHandler(scheduler -> Schedulers.trampoline());   RxAndroidPlugins.setInitMainThreadSchedulerHandler(schedulerCallable -> Schedulers.trampoline()); } Some of the tests are discussed below: →  The following test is written to ensure that the feedback list gets updated automatically after a feedback is received. @Test public void shouldLoadFeedbackListAutomatically() {   when(feedbackRepository.getFeedbacks(anyLong(), anyBoolean())).thenReturn(Observable.fromIterable(FEEDBACKS));   feedbackListPresenter.start();   verify(feedbackRepository).getFeedbacks(ID, false); } As can be seen above , I have used the when and return functionality of Mockito. It is basically used to check the return type of the object. So when the required parameters are passed in the getFeedback( ) , then the return type of what is expected is mentioned in the thenReturn( ). verify ensures that the getFeedback( ) is called on the feedbackfeedbackRepository mock only. → The following test is written to ensure that there is an error message on loading data after swipe refresh is made. Firstly the list of feedbacks is fetched from the feedbackRepository with the help of getFeedbacks( ) where the parameters event id and the boolean variable true are…

Continue ReadingImplement Tests for Feedback List in Open Event Orga App

Testing Presenter of MVP in Loklak Wok Android

Imagine working on a large source code, and as a new developer you are not sure whether the available source code works properly or not, you are surrounded by questions like, Are all these methods invoked properly or the number of times they need to be invoked? Being new to source code and checking manually already written code is a pain. For cases like these unit-tests are written. Unit-tests check whether the implemented code works as expected or not. This blog post explains about implementation of unit-tests of Presenter in a Model-View-Presenter (MVP) architecture in Loklak Wok Android. Adding Dependencies to project In app/build.gradle file defaultConfig { ... testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } dependencies { ... androidTestCompile 'org.mockito:mockito-android:2.8.47' androidTestCompile 'com.android.support:support-annotations:25.3.1' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' } Setup for Unit-Tests The presenter needs a realm database and an implementation of LoklakAPI interface. Along with that a mock of the View is required, so as to check whether the methods of View are called or not. The LoklakAPI interface can be mocked easily using Mockito, but the realm database can’t be mocked. For this reason an in-memory realm database is created, which will be destroyed once all unit-test are executed. As the presenter is required for each unit-test method we instantiate the in-memory database before all the tests start i.e. by annotating a public static method with @BeforeClass, e.g. setDb method. @BeforeClass public static void setDb() { Realm.init(InstrumentationRegistry.getContext()); RealmConfiguration testConfig = new RealmConfiguration.Builder() .inMemory() .name("test-db") .build(); mDb = Realm.getInstance(testConfig); }   NOTE: The in-memory database should be closed once all unit-tests are executed. So, for closing the databasse we create a public static method annotated with @AfterClass, e.g. closeDb method. @AfterClass public static void closeDb() { mDb.close(); }   Now, before each unit-test is executed we need to do some setup work like instantiating the presenter, a mock instance of API interface generated  by using mock static method and pushing in some sample data into the database. Our presenter uses RxJava and RxAndroid which depend on IO scheduler and MainThread scheduler to perform tasks asynchronously and these schedulers are not present in testing environment. So, we override RxJava and RxAndroid to use trampoline scheduler in place of IO and MainThread so that our test don’t encounter NullPointerException. All this is done in a public method annotated with @Before e.g. setUp. @Before public void setUp() throws Exception { // mocking view and api mMockView = mock(SuggestContract.View.class); mApi = mock(LoklakAPI.class); mPresenter = new SuggestPresenter(mApi, mDb); mPresenter.attachView(mMockView); queries = getFakeQueries(); // overriding rxjava and rxandroid RxJavaPlugins.setIoSchedulerHandler(scheduler -> Schedulers.trampoline()); RxAndroidPlugins.setMainThreadSchedulerHandler(scheduler -> Schedulers.trampoline()); mDb.beginTransaction(); mDb.copyToRealm(queries); mDb.commitTransaction(); }   Some fake suggestion queries are created which will be returned as observable when API interface is mocked. For this, simply two query objects are created and added to a List after their query parameter is set. This is implemented in getFakeQueries method. private List<Query> getFakeQueries() { List<Query> queryList = new ArrayList<>(); Query linux = new Query(); linux.setQuery("linux"); queryList.add(linux); Query india = new Query(); india.setQuery("india"); queryList.add(india); return queryList; }   After that, a method is…

Continue ReadingTesting Presenter of MVP in Loklak Wok Android

The Joy of Testing with MVP in Open Event Orga App

Testing applications is hard, and testing Android Applications is harder. The natural way an Android Developer codes is completely untestable. We are born and molded into creating God classes - Activities and perform every bit of logic inside them. Some thought that introduction to Fragments will introduce a little bit of modularity, but we proved otherwise by shifting to God Fragments. When the natural urge of an Android Developer to apply logic, load UI, handle concurrency (hopefully, not using AsyncTask), load data - from the network; disk; and cache, and manage the state of the Activity/Fragment finally, meets with a new form of revelation that he/she should test his/her application, all of the concepts acquired are shattered in a moment. The person goes to Android Docs to see why he started coding that way and realizes that even the system is flawed - Android Documentation is full of examples promoting God Activities, which they have used to show the use of API for only one reason - brevity. It’s not uncommon for us to steal some code from StackOverflow or Android Docs, but we don’t realize that they are presented there without an application environment or structure, all the required component just glued together to get it functionally complete, so that reader does not have to configure it anymore. Why would an answer from StackOverflow load a barcode scanner using a builder? Or build a ContentProvider to show how to query sorted data from SQLite? Or use a singleton for your provider classes? The simple answer is, they won’t. But this doesn’t mean you shouldn’t too. The first thought that enters developer’s mind when he gets his hand on a piece of code is to paste it in the correct position and get it to work. There is always this moment of hesitation where conscience rings a bell saying, “What are you doing? Is it the right way to do it? How many lines till you stop overloading this Activity? It’s 2000 lines already”. But it dies as soon as we see the feature is working. And why test something which we have confirmed to work, right? I just wrote this code to show a progress bar while the data loads and hide it when it is done. I can see this working, what will I achieve in painfully writing a test for it, mocking the loading conditions and all. Wrong! Unit tests which test your trivial utils like Date Modification, String Parsing, etc are good and needed but are so trivial that they are hard to go wrong, and if they are, they are easy to fix as they have single usage throughout the app, and it is easy to spot bugs and fix them. The real problem is testing of your app over dynamic conditions, where you have to emulate them so you can see if your app is making the right decisions. The progress bar working example may work for now, but what if it breaks over…

Continue ReadingThe Joy of Testing with MVP in Open Event Orga App