【问题标题】:How to mock Riverpod's Reader?如何模拟 Riverpod 的阅读器?
【发布时间】:2021-06-12 20:46:14
【问题描述】:

我有以下存储库,我想对其进行测试。我知道这可能是一个愚蠢的问题,但我仍在学习。

class AuthRepository implements AuthBaseRepository {
  final Reader _read;

  const AuthRepository(this._read);

  @override
  Future<User> login({String email, String password}) async {
    try {
      final response = await _read(dioProvider).post(
        '/sign_in',
        data: {
          "user": {
            "email": email,
            "password": password,
          },
        },
      );
      return _mapUserFromResponse(response);
    } on DioError catch (_) {
      throw const CustomException(message: 'Invalid login credentials.');
    } on SocketException catch (_) {
      const message = 'Please check your connection.';
      throw const CustomException(message: message);
    }
  }

这就是我到目前为止所做的:


void main() {
  test('loadUser', () async {
    Dio dio;
    DioAdapterMockito dioAdapterMockito;
    AuthRepository repository;

    setUpAll(() {
      dio = Dio();
      dioAdapterMockito = DioAdapterMockito();
      dio.httpClientAdapter = dioAdapterMockito;
      repository = AuthRepository(_reader_here_);
    });

    test('mocks any request/response via fetch method', () async {
      final responsePayload =
          await parseJsonFromAssets("assets/api-response.json");

      final responseBody = ResponseBody.fromString(
        responsePayload,
        200,
        headers: {
          Headers.contentTypeHeader: [Headers.jsonContentType],
        },
      );

      when(dioAdapterMockito.fetch(any, any, any))
          .thenAnswer((_) async => responseBody);
    });
  });
}

我不知道如何模拟 Reader。基本上,我见过class MyMock extends Mock implements Something 这样的东西,但Reader 不是一个类,它是一个函数,所以我完全迷路了。

任何帮助/提示/示例将不胜感激。

提前致谢!

【问题讨论】:

    标签: flutter unit-testing mockito provider riverpod


    【解决方案1】:

    不要尝试模拟Reader,而是为您的存储库创建一个提供程序并使用ProviderContainer 来读取它。

    class AuthRepository implements AuthBaseRepository {
      const AuthRepository(this._read);
    
      static final provider = Provider<AuthRepository>((ref) => AuthRepository(ref.read));
    
      final Reader _read;
    
      @override
      Future<User> login({String email, String password}) async {
        ...
      }
    
    

    示例用法:

    final user = createTestUser();
    
    final container = ProviderContainer(
      overrides: [
        // Example of how you can mock providers
        dio.overrideWithProvider(mockDio),
      ],
    );
    
    final repo = container.read(AuthRepository.provider);
    
    expectLater(
      await repo.login(email: 'AzureDiamond', password: 'hunter2'),
      user,
    );
    

    您还可以考虑使用 ProviderContainer 中的覆盖来模拟 Dio,而不是使用模拟框架来进一步简化您的测试。

    更多关于测试here

    【讨论】:

    • Alex,非常感谢您的 cmets。事实上,这就是我为存储库和控制器编写单元测试的方式。
    • @Ricbermo 乐于助人!如果这完全回答了您的问题,请将其标记为已接受。如果还有其他内容,我很乐意扩展。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    相关资源
    最近更新 更多