如何模拟 Riverpod 的 Reader?

How to mock Riverpod's Reader?

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

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 不是 class,它是一个函数,所以我完全迷路了。

任何help/tips/examples将不胜感激。

提前致谢!

与其尝试模拟 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