Flutter 中的 Mockito 缺少存根错误。尝试使用 Dio 的 post

Missing stub error on Mockito in Flutter. Trying to use post of Dio

我正在尝试使用 Dio 执行 post 请求并使用 Mockito 对其进行测试。但是我不知道为什么会出现这个错误,有人知道这是什么吗?

测试错误:

User Profile Image should verify if post method is successfully called [E]          
  MissingStubError: 'post'
  No stub was found which matches the arguments of this method call:
  post('/CadastroUsuario/test@example.com/salvarFotoPerfil', {data: Instance of 'FormData', queryParameters: null, options: null, cancelToken: null, onSendProgress: null, onReceiveProgress: null})
  
  Add a stub for this method using Mockito's 'when' API, or generate the mock for MockDio with 'returnNullOnMissingStub: true'.
  package:mockito/src/mock.dart 190:7                                 Mock._noSuchMethod
  package:mockito/src/mock.dart 184:45                                Mock.noSuchMethod
  test/data/c_user_registration_data_source_test.mocks.dart 147:14    MockDio.post
  package:app_test/data/c_user_registration_data_source.dart 70:33  CUserRegistrationDataSource.setUserProfileImage

我的测试代码:

group('User Profile Image', () {
    const email = 'test@example.com';

    var imagePath = File('test/assets/images/profile_image.png').path;
    var expectedUrl = uploadUserProfilePhotoPath.replaceFirst('{email}', email);

    test('should verify if post method is successfully called', () async {
      var formData = FormData.fromMap({
        'profileImage': await MultipartFile.fromFile(imagePath),
      });

      when(dio.post(
        expectedUrl,
        data: formData,
      )).thenAnswer(
        (_) async => Response(
          data: null,
          statusCode: 200,
          requestOptions: CommomMocks.getRequestOptions(expectedUrl),
        ),
      );

      await dataSource.setUserProfileImage(
        email: email,
        imagePath: imagePath,
      );

      verify(dio.post(expectedUrl, data: formData)).called(1);
    });
  });

实施:

@override
  Future<void> setUserProfileImage({
    required String email,
    required String imagePath,
  }) async {
    final http = _httpClientApp.instance();

    var apiUrl = uploadUserProfilePhotoPath.replaceFirst('{email}', email);
    var formData = FormData.fromMap({
      'profileImage': await MultipartFile.fromFile(imagePath),
    });

    final response = await http.post(apiUrl, data: formData);
    return _handleResponse(response);
  }

它表明缺少模拟 Dio 中的方法 post。我已经 运行 用于生成模拟的 pub 命令,并且在调用实现方法之前创建了存根。有什么我想念的吗?

提前致谢。

我认为问题出在 prod 函数中的“FormData”实例中:

var formData = FormData.fromMap({
    'profileImage': await MultipartFile.fromFile(imagePath),
});

每次测试运行时,都会创建一个新的实例,存根是不一样的。

所以我找到的解决方案是使用类型匹配器来检查是否使用函数调用了 'FormData' 类型的任何参数。

 test('should verify if post method is successful called', () async {
    httpStubs.setUpMockHttpClientAppSuccess(expectedUrl, formData);

    await dataSource.setUserProfileImage(
      email: email,
      imagePath: imagePath,
    );

    verify(
      () => httpClientApp.post(
        expectedUrl,
        body: isA<FormData>(),
      ),
    ).called(1);
  });

存根函数:

void setUpMockHttpClientAppSuccess(String url, dynamic payload) {
when(
  () => httpClientApp.post(
    any(),
    body: any(named: 'body'),
  ),
).thenAnswer(
  (_) async => Response(
    data: null,
    statusCode: 200,
    requestOptions: CommomMocks.getRequestOptions(url),
  ),
);

}

我不确定该解决方案是最佳解决方案还是最佳实践,因此这解决了我的测试问题。如果有人知道更好的解决方案,请告诉我。

感谢大家!! :)