Http 单元测试-如何在颤振中模拟第三方库类Dio的参数
我试图测试一个简单的repository类,它使用依赖项注入的Dio包进行网络调用。Http.post的要求是向URL发送一个映射对象,其标题为Http 单元测试-如何在颤振中模拟第三方库类Dio的参数,http,flutter,dart,mockito,flutter-test,Http,Flutter,Dart,Mockito,Flutter Test,我试图测试一个简单的repository类,它使用依赖项注入的Dio包进行网络调用。Http.post的要求是向URL发送一个映射对象,其标题为'Content-Type':'application/json。您可以在下面看到: class AuthenticateUserRemoteDataSourceImpl implements AuthenticateUserRepository { final Dio httpClient; AuthenticateUserRemot
'Content-Type':'application/json
。您可以在下面看到:
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'}));
}
}
谢谢你的帮助,我才刚刚开始单元测试,所以任何帮助或指点都会很好
谢谢,山姆
@爱
更新
我已经实现了你的模拟类,效果非常好,我想这是我肯定错过的东西。我已经更新了我的测试,但不知道我现在哪里出了问题
飞镖
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)));
});
类MockOptions扩展了Mock实现选项{
最终地图标题;
//还可以添加任何其他要模拟为此类中的字段的参数
MockOptions({this.headers});
}
试验(
'应使用application/json头对API执行post请求',
()异步{
//安排
映射头={'Content-type':'application/json'};
当(mockDio.post('path',options:anyNamed('options'))
.thenAnswer(()async=>Response(数据:{}));
//表演
dataSource.getAuthenticateUser(tEmail,tPassword);
//断言
验证(mockDio.post('path',选项: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'}));
}
@覆盖
未来的认证者(
字符串电子邮件,字符串密码)异步{
等待这个.httpClient.post('path',
数据:{},
选项:选项(标题:{'Content-type':'application/json'});
}
以测试此方法
Response response = await httpClient.post('{$url}api/users/authenticate',
data: jsonPayload,
options: Options(headers: {'Content-Type': 'application/json'}));
如果使用正确的参数调用,则应创建一个MockOption
类,并将其实例传递给测试中的函数调用
此外,您还应该创建一个类型为Map
(或json使用的任何类型)的对象,并将该对象也传递给对data
参数的相同方法调用
然后使用Mockito
的方法验证是否使用已传递的测试参数调用了方法
还要测试您按照我在这里所说的有关地图的标题:
此外,还应创建类型为Map
(或
json使用的任何类型)并将该对象也传递给相同的
方法调用
请看一下我的答案
更新:
例如,要模拟选项
参数,可以执行以下操作:
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);
}
使用新软件包模拟Dio
请求。
您只需将插入的Dio
的httpClientAdapter
替换为DioAdapter()
:
来自
import'包:dio/dio.dart';
导入“包:http_mock_adapter/http_mock_adapter.dart”;
void main()异步{
最终dio=dio();
最终dioAdapter=dioAdapter();
dio.httpClientAdapter=dioAdapter;
常数路径https://example.com';
双适配器
…昂吉(
路径
(request)=>request.reply(200,{'message':'Successfully mocked GET!'),
)
…昂吉(
路径
(request)=>request.reply(200,{'message':'Successfully mocked POST!'}),
);
最终onGetResponse=等待dio.get(路径);
打印(onGetResponse.data);//{message:Successfully mocked GET!}
最终onPostResponse=等待dio.post(路径);
打印(onPostResponse.data);//{message:Successfully mocked POST!}
}
您还可以使用,DioInterceptor
of,它可以添加到dio.interceptor
列表中
查看文件中的第二个示例嘿,巴德,谢谢你的回答。我还是想不出来。休息了几周后,我又回到了这里,但仍然没有什么乐趣。我已经把它的赏金现在,如果可能的话,你能给我更多的指示如何模拟反应会是什么样子?当我尝试模拟选项类时,我无法向该类添加任何命名参数。这是模拟类的一个限制吗?你的意思是不能将
data:anyNamed('data')
替换为,例如,data:myData
?我在原始问题上添加了一个屏幕截图谢谢,我没有想到向模拟类添加参数。很好,我已经用一个更新的问题更新了我的问题,在使用你的命名参数解决方案后,你能发现我更新的测试出了什么问题吗?在when
func中,我正在传递anyNamed
,因为这不需要是MockOptions
的实例。我只需要验证是否使用正确的选项调用了该方法。还是我又误解了?
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);
}
final MockOptions mockOptions = MockOptions({
//mocked map data here
});