# Flutter Unit Testing with Mockito:

In the previous [article](https://harishkunchala.com/unit-testing-in-flutter-with-examples#heading-example-2-http-user-app). 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](https://pub.dev/packages/mockito) documentation.

### Source Code:

Also you can find the source code here: [users\_http\_test/mockito branch](https://github.com/khkred/flutter_testing_examples/tree/mockito_testing/unit_testing/users_http_test)

### 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`:

```bash
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](http://jsonplaceholder.com). To test this, we are going to pass the `http.Client` as an argument to the function.

```dart
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 `MockClient`class 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.
    

```dart
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:

```bash
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:

```dart
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:

```bash
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](https://pub.dev/packages/mockito).

So good luck with your programming journey and happy coding 🐦
