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:
Add the package dependencies.
Create a function to test.
Create a test file with a mock
http.Client
.Write a test for each condition.
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 roottest
folder.Add the annotation
@GenerateMocks([http.Client])
to the main function to generate aMockClient
class withmockito
.The generated
MockClient
class implements thehttp.Client
class. This allows you to pass theMockClient
to theuserAlbum
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:
Returns an Album JSON if the http call succeeds.
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 🐦