Flutter Unit Testing with Mockito:

Flutter Unit Testing with Mockito:

In the previous article. We saw how to run the tests using Mocktail. In here we are going to look at how to do it using Mockito.

Mocks allow emulating a live web service or database and return specific results depending on the situation.

In here we are going to couple of things:

  1. Add the package dependencies.

  2. Create a function to test.

  3. Create a test file with a mock http.Client.

  4. Write a test for each condition.

  5. Run the tests.

For more information, see the Mockito package documentation.

Source Code:

Also you can find the source code here: users_http_test/mockito branch

1. Add the package dependencies:

To the use the mockito package, let's add it to pubspec.yaml

mockito: 5.0.0 supports Dart's null safety thanks to code generation. To run the required code generation, add the build_runner dependency in the dev_dependencies section.

To add the dependencies, run flutter pub add:

flutter pub add dev:mockito dev:build_runner

2. Create a function to test

In the previous article, we got a User from jsonplacholder.com

In here we are going to create a function to get a single album from jsonplaceholder.com. To test this, we are going to pass the http.Client as an argument to the function.

import 'dart:convert';  

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

class UserAlbum {  
  final http.Client client;  

  UserAlbum({required this.client});  

  Future<Map<String, dynamic>> fetchAlbum() async {  
    final response = await client  
        .get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));  

    if (response.statusCode == 200) {  
      final responseBody = jsonDecode(response.body);  

      return responseBody as Map<String, dynamic>;  
    } else {  
      throw Exception('Failed to load album');  
    }  
  }  
}

3. Create a test file with a mock http.Client

  • Following the advice from previous article let's create a user_album_test.dart in the root test folder.

  • Add the annotation @GenerateMocks([http.Client]) to the main function to generate a MockClientclass with mockito.

  • The generated MockClient class implements the http.Client class. This allows you to pass the MockClient to the userAlbum class, and return different http responses in each test.

import 'package:http/http.dart' as http;  
import 'package:users_http_test/user_album.dart';  
import 'package:mockito/annotations.dart';  

// Generate a MockClient using the Mockito package.  
// Create new instances of this class in each test.  
@GenerateMocks([http.Client])  
void main() {  
}

Next, generate the mocks running the following command:

dart run build_runner build

4. Write a test for each condition

The fetchAlbum() function does one of two things:

  1. Returns an Album JSON if the http call succeeds.

  2. Throws an Exception if the http call fails

Therefore, you want to test these two conditions. Use the MockClient class to return an "Ok" response for the success test, and an error response for the unsuccessful test. Test these conditions using the when() function provided by Mockito:

import 'package:flutter_test/flutter_test.dart';  
import 'package:http/http.dart' as http;  
import 'package:mockito/mockito.dart';  
import 'package:users_http_test/user_album.dart';  
import 'package:mockito/annotations.dart';  

import 'user_album_test.mocks.dart';  

// Generate a MockClient using the Mockito package.  
// Create new instances of this class in each test.  
@GenerateMocks([http.Client])  
void main() {  
  group('fetchAlbum', () {  
    test('Given an UserAlbum Class, when fetchAlbum() is called then return an JSON IF THE HTTP call completes successfully', () async {  
      final client = MockClient();  

      // Use Mockito to return a successful response when it calls the  
      // provided http.Client.      when(client.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'))).thenAnswer((_) async {  
        return http.Response('{"userId": 1, "id": 2, "title": "mock"}', 200);  
      });  

      final userAlbum = UserAlbum(client: client);  

      expect(await userAlbum.fetchAlbum(), isA<Map<String,dynamic>>());  
    });  

    test('Given an UserAlbum Class, when fetchAlbum() is called, then throws an exception if http call completes with an error', () async {  
      final client = MockClient();  

      // Use Mockito to return an unsuccessful response when it calls the  
      // provided http.Client.      
           when(client.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'))).thenAnswer((_) async => http.Response('Not Found', 404));  

      final userAlbum = UserAlbum(client: client);  
      expect(userAlbum.fetchAlbum(), throwsException);  
    });  
  });  
}

5. Run the tests

Now that we have a fetchAlbum() functions with tests in place, run the tests:

flutter test test/user_album_test.dart

And looks like all the tests passed. So we've learned how to use the Mockito package, I would recommend that you read up more by reading the documentation provided by the Mockito package.

So good luck with your programming journey and happy coding 🐦

Did you find this article valuable?

Support Harish Kunchala by becoming a sponsor. Any amount is appreciated!