Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 单元测试-如何在颤振中模拟第三方库类Dio的参数_Http_Flutter_Dart_Mockito_Flutter Test - Fatal编程技术网

Http 单元测试-如何在颤振中模拟第三方库类Dio的参数

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

我试图测试一个简单的repository类,它使用依赖项注入的Dio包进行网络调用。Http.post的要求是向URL发送一个映射对象,其标题为
'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
            });