使用 Mockito 的 'when' API 为方法添加存根时出错

2023-12-25

有这个抽象类可以从远程数据源获取数据

abstract class NumberTriviaRemoteDataSource {
  /// Calls the http://numberapi.com/{number} endpoint.
  ///
  /// Throws a [ServerException] for all error code
  Future<NumberTriviaModel> getConcreteNumberTrivia(int number);
}

并在域层中有这个存储库的抽象类

abstract class NumberTriviaRepository {
  Future<Either<Failure, NumberTrivia>> getConcreteNumberTrivia(int number);
}

下面我创建了一个测试来实现NumberTriviaRepository class

@GenerateMocks([NumberTriviaRemoteDataSource])
void main() {
  late final NumberTriviaRepositoryImpl repository;
  late final MockNumberTriviaRemoteDataSource mockRemoteDataSource;
  setUp(() {
    mockRemoteDataSource = MockNumberTriviaRemoteDataSource();
    repository = NumberTriviaRepositoryImpl(
      numberTriviaRemoteDataSource: mockRemoteDataSource,
    );
  });
  group('getConcreteNumberTrivia', () {
    //to make test manageable create variables
    const tNumber = 1;
    const tNumberTriviaModel =
        NumberTriviaModel(text: 'test trivia', number: tNumber);
    const NumberTrivia tNumberTriviaEntity = tNumberTriviaModel;

    group('when device is online', () {
      test(
          'should return remote data when call to remote data source is successful',
          () async {
        //arrange                                
        when(mockRemoteDataSource.getConcreteNumberTrivia(any))  
            .thenAnswer((_) async => tNumberTriviaModel);               ---> Line *
        //act
        final result = await repository.getConcreteNumberTrivia(tNumber);
        //assert
        verify(mockRemoteDataSource.getConcreteNumberTrivia(tNumber));
        expect(result, equals(const Right(tNumberTriviaEntity)));
      });
    });
  });

下面我实现了NumberTriviaRepository class

class NumberTriviaRepositoryImpl implements NumberTriviaRepository {
  NumberTriviaRemoteDataSource numberTriviaRemoteDataSource;
  NumberTriviaRepositoryImpl(
      {required this.numberTriviaRemoteDataSource});
  @override
  Future<Either<Failure, NumberTrivia>> getConcreteNumberTrivia(
      int number) async {
    return Right(
        await numberTriviaRemoteDataSource.getConcreteNumberTrivia(number));
  }

当运行测试时我得到一个Mock.noSuchMethod error :

MissingStubError: 'getConcreteNumberTrivia'
No stub was found which matches the arguments of this method call:
getConcreteNumberTrivia(1)

解释如下:“使用 Mockito 的 'when' API 添加此方法的存根,或者使用带有 'returnNullOnMissingStub: true' 的 MockSpec 生成 MockNumberTriviaRemoteDataSource 模拟(请参阅https://pub.dev/documentation/mockito/latest/annotations/MockSpec-class.html https://pub.dev/documentation/mockito/latest/annotations/MockSpec-class.html)."

问题是我在 * 行为 getConcreteNumberTrivia 创建了一个存根方法,但出现错误,并且不知道如何解决此问题。顺便说一句,我正在使用 TestDrivenDevelopment 学习清洁架构,因此任何评论都会受到重视。


使用 setUpAll() 初始化模拟并在 setUpAll 部分中使用 when

@GenerateMocks([NumberTriviaRemoteDataSource])
@GenerateMocks([NumberTriviaLocalDataSource])
@GenerateMocks([NetworkInfo])
void main() {
  late final NumberTriviaRepositoryImpl repository;
  late final MockNumberTriviaRemoteDataSource mockRemoteDataSource;
  late final MockNumberTriviaLocalDataSource mockLocalDataSource;
  late final MockNetworkInfo mockNetworkInfo;

  const tNumber = 1;
  const tNumberTriviaModel =
      NumberTriviaModel(text: 'test trivia', number: tNumber);
  const NumberTrivia tNumberTriviaEntity = tNumberTriviaModel;
  setUpAll(() {
    mockRemoteDataSource = MockNumberTriviaRemoteDataSource();
    mockLocalDataSource = MockNumberTriviaLocalDataSource();
    mockNetworkInfo = MockNetworkInfo();
    repository = NumberTriviaRepositoryImpl(
      numberTriviaRemoteDataSource: mockRemoteDataSource,
      numberTriviaLocalDataSource: mockLocalDataSource,
      networkInfo: mockNetworkInfo,
    );

    when(mockRemoteDataSource.getConcreteNumberTrivia(any))
        .thenAnswer((_) async => tNumberTriviaModel);
  });
  group('getConcreteNumberTrivia', () {
    //to make test manageable create variables

    test('should check if the device is online', () {
      //arrange
      when(mockNetworkInfo.isConnected).thenAnswer((_) async => true);
      // act
      repository.getConcreteNumberTrivia(tNumber);
      // assert
      verify(mockNetworkInfo.isConnected);
    });
    group('when device is online', () {
      setUp(() {
        when(mockNetworkInfo.isConnected).thenAnswer((_) async => true);
      });
      test(
          'should return remote data when call to remote data source is successful',
          () async {
        //arrange
        when(mockRemoteDataSource.getConcreteNumberTrivia(any))
            .thenAnswer((_) async => tNumberTriviaModel);

        //act
        final result = await repository.getConcreteNumberTrivia(tNumber);
        //assert
        verify(mockRemoteDataSource.getConcreteNumberTrivia(tNumber));
        expect(result, equals(const Right(tNumberTriviaEntity)));
      });
  });
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Mockito 的 'when' API 为方法添加存根时出错 的相关文章

随机推荐