如何模拟 Riverpod 的阅读器?

问题描述

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

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

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

提前致谢!

解决方法

不要尝试模拟 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 的更多信息。