问题描述
我正在尝试测试一个简单的存储库类,该类使用依赖注入的Dio包进行网络调用.Http.post的要求是将Map对象发送到标有'Content-Type':'application/json
的URL.您可以在下面看到此内容:
I am trying to test a simple repository class which make a network call using the Dio package that is a dependency injection. Requirement of the Http.post is to send a Map object to a URL with the headers of 'Content-Type': 'application/json
. You can see this below:
class AuthenticateUserRemoteDataSourceImpl
implements AuthenticateUserRepository {
final Dio httpClient;
AuthenticateUserRemoteDataSourceImpl({@required this.httpClient});
@override
Future<Either<Failure, AuthenticateUser>> getAuthenticateUser(
String email, String password) async {
final url = 'API_URL';
final Map<String, String> jsonPayload = {
"email": email,
"password": password
};
Response response = await httpClient.post('{$url}api/users/authenticate',
data: jsonPayload,
options: Options(headers: {'Content-Type': 'application/json'}));
}
}
我试图确保此方法已包含在单元测试中,但是我很难用Dio包验证命名的参数.我可以验证 dioClient.post
是否确实被调用,但是,我在模拟'data'和'options'的名称参数时遇到麻烦.
I am trying to make sure this method is covered by unit test, however I am having difficult verify the named parameters with the Dio package. I can verify that the dioClient.post
is actually called however, I am having trouble with mocking the name parameters of 'data' and 'options'.
我想测试是否使用主体的 Map< String,String>
调用它,并且我也想测试发送的标头,我想检查它是否被调用使用 {'Content-Type':'application/json'}
.当我需要对已验证的dio get/post/put请求进行单元测试时,这也将非常有用.
I want to test that it gets called with Map<String, String>
for the body, and also I would like to test the headers that are sent, I want to check that is it called with the {'Content-Type': 'application/json'}
. This will be useful as well when I need to unit test Authenticated dio get/post/put requests.
这是我到目前为止所进行的测试,如前所述,我可以验证模拟函数是否已调用,但不验证名称params.
This is the test that I have so far, which as mentioned before I can verify that the mocked function is called, but not verifying the name params.
group('getAuthenticateUser', () {
final tResponse = Response(statusCode: 200, data: {"title": "success"});
test(
'should perform a post request to the the API with the application/json header',
() async {
// arrange
when(dioClient.post(any,
data: anyNamed('data'), options: anyNamed('options')))
.thenAnswer((Invocation invocation) async => tResponse);
// act
await dataSource.getAuthenticateUser(tEmail, tPassword);
// assert
verify(dioClient.post(any,
data: anyNamed('data'), options: anyNamed('options')));
});
});
感谢您的帮助,我才刚刚开始进行单元测试,因此任何帮助或指示都将非常有用,
Thanks for your helps, I am just getting started with unit testing so any help or pointers will be great,
谢谢,山姆
@爱
更新
我实现了您的模拟类,效果很好,我认为那是我肯定缺少的东西.我已经更新了测试,但现在不知道我要去哪里错了?
I have implemented your mock class which worked great, and I think it was the thing that I was missing for sure. I have updated my test but cannot understand where I am going wrong now?
test.dart
test.dart
class MockOptions extends Mock implements Options {
final Map<String, dynamic> headers;
//also add any other parameters you want to mock as fields in this class
MockOptions({this.headers});
}
test(
'should perform a post request to the the API with the application/json header',
() async {
// arrange
Map<String, String> headers = {'Content-type': 'application/json'};
when(mockDio.post('path', options: anyNamed('options')))
.thenAnswer((_) async => Response(data: {}));
// act
dataSource.getAuthenticateUser(tEmail, tPassword);
// assert
verify(mockDio.post('path', options: MockOptions(headers: headers)));
});
和方法文件如下所示:
@override
Future<Either<Failure, AuthenticateUser>> getAuthenticateUser(
String email, String password) async {
await this.httpClient.post('path',
data: {},
options: Options(headers: {'Content-type': 'application/json'}));
}
推荐答案
使用 http_mock_adapter ,新软件包用于模拟 Dio
请求.
您可以简单地将注入的 Dio
的 httpClientAdapter
替换为DioAdapter().dev/packages/http_mock_adapter"rel =" nofollow noreferrer> http_mock_adapter :
Use http_mock_adapter, new package for mocking Dio
requests.
You can simply replace your injected Dio
's httpClientAdapter
with DioAdapter()
of http_mock_adapter:
个示例packages/http_mock_adapter"rel =" nofollow noreferrer> http_mock_adapter
example from examples of http_mock_adapter
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:http_mock_adapter/http_mock_adapter.dart';
import 'package:flutter_test/flutter_test.dart';
void main() async {
// How to mock with DioAdapter
group('DioAdapter usage', () {
// Creating dio instance for mocking.
// For instance: you can use your own instance from injection and replace
// dio.httpClientAdapter with mocker DioAdapter
final dio = Dio();
final dioAdapter = DioAdapter();
dio.httpClientAdapter = dioAdapter;
const path = 'https://example.com';
test('Expects Dioadapter to mock the data', () async {
dioAdapter
.onGet(path)
.reply(200,
{'message': 'Successfully mocked GET!'}) // only use double quotes
.onPost(path)
.reply(200, {'message': 'Successfully mocked POST!'});
// Making dio.get request on the path an expecting mocked response
final getResponse = await dio.get(path);
expect(jsonEncode({'message': 'Successfully mocked GET!'}),
getResponse.data);
// Making dio.post request on the path an expecting mocked response
final postResposne = await dio.post(path);
expect(jsonEncode({'message': 'Successfully mocked POST!'}),
postResposne.data);
});
});
}
您还可以使用 http_mock_adapter 的 DioInterceptor
添加到 dio.interceptor
列表中.
在示例文件中查看第二个示例.dev/packages/http_mock_adapter"rel =" nofollow noreferrer> http_mock_adapter
You can also use, DioInterceptor
of http_mock_adapter, which can be added to dio.interceptor
list.
view second example in examples file of http_mock_adapter
这篇关于单元测试-如何在Flutter中模拟第三方库类Dio的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!