使用mocktail包进行单元测试时,类型“Null”不是类型“Future<void>”的子类型

joh*_*ohn 4 testing unit-testing mocking flutter

我们如何验证函数内的方法是否被调用?我这里有一个示例代码。

class MockService extends Mock implements Service {}

class MockRepository extends Mock implements Repository {}

class Repository {
  Repository({
    required this.service,
  });
  final Service service;

  Future<void> somethingFancy() async {
    await service.doSomething();
  }
}

class Service {
  Future<void> doSomething() async {}
}

void main() {
  final service = MockService();
  final repository = Repository(service: service);

  group('auth repository test', () {
    test('test name', () async {
      when(repository.somethingFancy).thenAnswer((_) => Future.value());
      await repository.somethingFancy();

      verify(service.doSomething).called(1);
    });
  });
}
Run Code Online (Sandbox Code Playgroud)

如果我运行测试,我会收到此错误:

type 'Null' is not a subtype of type 'Future<void>'
test/auth_repository_test.dart 20:16      MockService.doSomething
test/auth_repository_test.dart 15:19      Repository.registerUser
package:mocktail/src/mocktail.dart 210:8  when.<fn>
test/auth_repository_test.dart 29:11      main.<fn>.<fn>
===== asynchronous gap ===========================
dart:async                                _completeOnAsyncError
package:mocktail/src/mocktail.dart 210:8  when.<fn>
test/auth_repository_test.dart 29:11      main.<fn>.<fn>
Run Code Online (Sandbox Code Playgroud)

如果我将存储库变量更改为final repository = MockRepository();,我无法注入Service class,因此肯定不会调用服务类内的方法。这就是为什么我运行这个测试:

void main() {
  final service = MockService();
  final repository = MockRepository();

  group('auth repository test', () {
    test('test name', () async {
      when(repository.somethingFancy).thenAnswer((_) => Future.value());
      await repository.somethingFancy();

      verify(service.doSomething).called(1);
    });
  });
}
Run Code Online (Sandbox Code Playgroud)

我收到一条错误消息no matching calls

No matching calls (actually, no calls at all).
(If you called `verify(...).called(0);`, please instead use `verifyNever(...);`.)
package:test_api                           fail
package:mocktail/src/mocktail.dart 722:7   _VerifyCall._checkWith
package:mocktail/src/mocktail.dart 515:18  _makeVerify.<fn>
test/auth_repository_test.dart 32:13       main.<fn>.<fn>
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么?感谢这么多的帮助。

pow*_*rus 6

您在测试中使用了错误的方法。

你必须模拟答案Service#doSomething而不是Repository#doSimethingFancy. 检查你的when陈述。

test('test name', () async {
  when(service.doSomething()).thenAnswer((_) => Future.value());
  await repository.somethingFancy();

  verify(service.doSomething).called(1);
});
Run Code Online (Sandbox Code Playgroud)