Mock Dio in Flutter

Shan Shaji
4 min readJul 5, 2021

--

The http-mock-adapter package can be used for mocking dio. You can find the package from pub.dev.

click here to view the package.

The package has a good readme you can either follow the steps from the readme or you can follow along.

http-mock-adapter is a simple to use mocking package for Dio. It helps us to mock the request response communication.

Installing http-mock-adapter

You can skip this section if you are aware of adding dev dependencies in flutter.

I am going to follow the same steps from the official readme.

You can quickly install the package from command line. Type the below command, after pressing enter the package will be added to the dev dependencies section in pubspec.yaml.

flutter pub add --dev http_mock_adapter
The package will be added in the dev_dependencies section

For Manual Install

Copy and paste the dependency to the dev_dependencies section.

http_mock_adapter: ^0.3.1

Install it

You can then install the package from the command-line:

With dart:

$ dart pub get

With flutter:

$ flutter pub get

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Testing Dio

import 'package:dio/dio.dart';
import 'package:http_mock_adapter/http_mock_adapter.dart';

void main() async {
final dio = Dio();
final dioAdapter = DioAdapter();

dio.httpClientAdapter = dioAdapter;

const path = 'https://example.com';

dioAdapter.onGet(
path,
(request) => request.reply(200, {'message': 'Success!'}),
);

final response = await dio.get(path);

print(response.data); // {message: Success!}
}

This is an example that is given in the package readme that will give you a brief idea of how this package actualy works.

In this example we have a dart file which consist only one main function. At first we need to import the packages.

import 'package:dio/dio.dart';
import 'package:http_mock_adapter/http_mock_adapter.dart';

Inside the main function we are creating the instance of two classes.

final dio = Dio();
final dioAdapter = DioAdapter();

After that we are attatching the new instance to dio’s httpClientAdapter.

dio.httpClientAdapter = dioAdapter;

we need to specify the path to which that we are going to make the requests.

const path = 'https://example.com'; // this is a dummy endpoint

Here the dioAdapter.onGet method can Mock thhe get method in dio

dioAdapter.onGet(
path,
(request) => request.reply(200, {'message': 'Success!'}),
);
final response = await dio.get(path);

print(response.data); // {message: Success!}

So here when we call the dio.get method we will get a response as

{message: Success!}

Example — unit testing an ApiService class having dio http methods

import 'dart:io';
import 'package:dio/dio.dart';

import 'exceptions/exceptions.dart';

class ApiService {
final String _baseURL = 'https://example.com/';
Dio _dio = Dio();

ApiService({Dio? dio}) {
_dio = dio ?? Dio(); /// Dependency Injection
_dio.options.baseUrl = _baseURL;
}

Future<dynamic> get(String path) async {
var responseJson;
try {
final response = await _dio.get(_baseURL + path);
responseJson = returnResponse(response);
} on SocketException {
throw FetchDataException('No Internet connection');
}
return responseJson;
}

@override
Future<dynamic> post(String path, dynamic data) async {
var responseJson;
try {
final response = await _dio.post(_baseURL + path,
data: data,
options: Options()..headers = {'Content-Type': 'application/json'});
responseJson = returnResponse(response);
} on SocketException {
throw FetchDataException('No Internet connection');
}
return responseJson;
}

@override
dynamic returnResponse(Response response) {
switch (response.statusCode) {
case 200:
case 201:
case 404:
return response.data;
case 400:
throw InvalidRequestException(response.data.toString());
case 401:
case 403:
throw UnauthorisedException(response.data.toString());
case 500:
default:
throw FetchDataException(
'Error occurred while Communication with Server with StatusCode : ${response.statusCode}',
);
}
}
}

The code above is the implimentation of ApiService class. We will be testing the methods within this ApiService class.

/// These are some test messages and paths 
const successMessage = {'message': 'Success'};
const errorMessage = {'message': 'error'};
const testPath = 'test';
const testData = {'data': 'sample data'};
const header = {'Content-Type': 'application/json'};
import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter_app/api.dart';
import 'package:flutter_app/exceptions/exceptions.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:http_mock_adapter/http_mock_adapter.dart';


import 'test_constants.dart';


void main() {
final dio = Dio();
final dioAdapter = DioAdapter();
var baseUrl;

setUp(() {
dio.httpClientAdapter = dioAdapter;
baseUrl = 'https://example.com/';
});

group('- ApiService class methods test', () {
group('- Get Method', () {
test('- Get Method Success test', () async {

dioAdapter.onGet(
'$baseUrl$testPath',
(request) {
return request.reply(200, successMessage);
},
data: null,
queryParameters: {},
headers: {},
);


final service = ApiService(
dio: dio,
);

final response = await service.get('test');

expect(response, successMessage);
});
});

group('- Post Method', () {
test('- Post Method Success test', () async {

dioAdapter.onPost(
'$baseUrl$testPath',
(request) {
return request.reply(201, successMessage);
},
data: json.encode(testData),
queryParameters: {},
headers: header,
);


final service = ApiService(
dio: dio,
);

final response = await service.post('test', json.encode(testData));

expect(response, successMessage);
});
});
});
}

The above code is the test function that tests the functions inside the ApiService class. I will be providing the project link at the end of this article.

You can find the full code from here

--

--

Shan Shaji

Skilled in Flutter, React, MongoDB, Express, and Typescript. Experienced with Flutter architectures, state management, Firebase, and cloud functions.