如何模拟 Riverpod 的 Reader?

Ric*_*rmo 1 provider unit-testing mockito flutter 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);
    }
  }

Run Code Online (Sandbox Code Playgroud)

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


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);
    });
  });
}
Run Code Online (Sandbox Code Playgroud)

我不知道如何嘲笑读者。基本上,我见过类似的东西class MyMock extends Mock implements Something,但它Reader不是一个类,它是一个函数,所以我完全迷失了。

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

提前致谢!

Ale*_*ord 9

不要尝试模拟 a 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 {
    ...
  }

Run Code Online (Sandbox Code Playgroud)

用法示例:

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,
);
Run Code Online (Sandbox Code Playgroud)

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

有关测试的更多信息请参见此处