Unit Testing In Flutter With Mockito
By: Apoorv Wadhwa
Tags: Flutter, Continous Deployment, Continuous Integration, Mockito, Testing

It is possible to make unit tests which call to a live server or a database but, doing so would either consume too much time or give unexpected results

Instead of relying on that, the Flutter team has provided us with a fantastic package for mocking dependencies, called Mockito.

What Mockito does is that, it emulates a dummy database and gives us returns based on our results.

So imagine you have a simple function that uses the HTTP package and then fetches results from the database and based on the result aka status code returns either exception or the JSON we required

So let's write the code for it

Future fetchFromDatabase(http.Client client) async {

final response =

await client.get('https://jsonplaceholder.typicode.com/posts/1');



if (response.statusCode == 200) {

return jsonDecode(response.body);

} else {

throw Exception('exception occured!!!!!!');

}

}

In the above code, you can see we created a function that takes an http.Client parameter and on it performs the get operation and provides values to the response variable, and then we check if the response’s status code was 200 which means it was successful or if it was something else then it means the call was a failure and based on the that we return either the json we needed or the exception.

Clear so far? Alright, now we move on to using Mockito to test this function and check it performs accordingly.

first of all please add the dependency for Mockito, as of writing this blog the version 4.1.3 is the highest, but please check pub.dev for the latest version, also add the HTTP package too.

mockito: ^4.1.3 http: ^0.12.2

After that is done we will need to create a class that extends the Mock from mockito package and also implements the http.Client

So for that, we will import the http/http.dart as http like so

import 'dart:convert';



import 'package:flutter_test/flutter_test.dart';

import 'package:mockito/mockito.dart';

import 'package:http/http.dart' as http;

These are all of my imports needed for this

Now on to creating the class

class MockitoExample extends Mock implements http.Client {



}

Now what this actually does is that instead of connecting to a live web service or database it actually cuts off and connects to our mock class which allows us to test by providing various results and test it under different conditions

Moving on now we will write test cases, so for a general idea about unit testing in flutter, you can refer to my previous blog post here.

So first we make a instance of our MockitoExample class and call it mockitoExample and use it in our tests.

Mockito also provides us when and thenAnswer methods which make testing a whole lot easier.

First we will test it in case of Success

test('returns a Map if there is no error', () async {

http.Client mockitoExample = MockitoExample();



when(mockitoExample.get('https://jsonplaceholder.typicode.com/posts/1'))

.thenAnswer((value) async {

http.Response('{"title": "Test"}', 200);

});



expect(await fetchFromDatabase(mockitoExample), isA<Map>());

});

In the above code snippet you can see I have written a test scenario in which the description is “return a map if there is no error”

Now inside When I have used the mockitoExample’s .get() method to get the data from the API, and in the then Answer, I am simply returning the http.Response along with the status code 200 means that it was a success.

Now in the expected part of the test, we use the function we created above-called fetchFromDatabase and provide it our mockitoExample as http.client, which will return us a success, and then we use isA() method in the matcher part of the expect function which is basically a typeMatcher provided to us in the test/flutter_test import, in which we have taken the generic type as a Map since we will be getting a map from the fetchFromDatabase function in this particular case.

Now we test in case of an Error

test('gives us an exception if we get error in our http call', () {

final mockitoExample = MockitoExample();



when(mockitoExample.get('https://jsonplaceholder.typicode.com/posts/1'))

.thenAnswer((value ) async {

return http.Response('Not Found', 404);

});



expect(fetchFromDatabase(mockitoExample), throwsException);

});

This is almost the same as before, we created an instance of MockitoExample, then we passed the same API in when and provided status code 404 in the http.Response part.

Now in the expect we called the fetchFromDatabase function and provided it our mockitoExample as a client and in the matcher part we used throwsException because we know it will give us an exception if the status code is not 200.

That’s just the basic example of writing mock tests using the Mockito package to mock dependencies.

Most of the code idea is taken from the official documentation of Mockito just a bit modified so that it's easier to understand by everyone.

Write to me in the comments for any problem you face implementing this I will try my best to help you ASAP.

That’s it for this blog lets meet in the next one.