本文介绍了单元测试-如何在Flutter中模拟第三方库类Dio的参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试一个简单的存储库类,该类使用依赖注入的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的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 12:18