Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dart & Mockito. How to call Function() argument in mocked method

Tags:

mockito

dart

I use Mockito for writing tests on Flutter. I have a mocked class and method with arguments that are functions - Function() and this method returns StreamSubscription. I need to pass these arguments to the call of listen() function but can't find a way to do it. (See example) Could somebody help me, please?

I tried to pass them with argThat(anyNamed('nameOfArgument') like in the example, but tests trows error - The "anyNamed" argument matcher is used outside of method stubbing (via when)

class MockPhotoLibraryService extends Mock implements PhotoLibraryService {}

PhotoLibraryService setupMockPhotoLibraryService() {
  final photoLibraryService = MockPhotoLibraryService();

  when(
    photoLibraryService.getPhotosForPeriod(
        onData: anyNamed('onData'),
        onDone: anyNamed('onDone'),
        onError: anyNamed('onError')),
  ).thenAnswer((_) => Stream<Photo>.fromFuture(
          Future<Photo>.delayed(Duration(milliseconds: 50), () => Photo()))
      .listen(argThat(anyNamed('onData')), //need to pass argument named onData
          onDone: argThat(anyNamed('onDone')), //need to pass argument named onDone
          onError: argThat(anyNamed('onError')), //need to pass argument named onError
          cancelOnError: true));

  return photoLibraryService;
}

I need these arguments functions to be called by the Future for the correct work of my testable widget.

like image 747
Valentyn Smaha Avatar asked Mar 03 '23 07:03

Valentyn Smaha


1 Answers

You can get access to the original call parameters through Invocation object. It is passed as a parameter to the thenAnswer callback function.

when(photoLibraryService.getPhotosForPeriod(
  onData: anyNamed('onData'),
  onDone: anyNamed('onDone'),
  onError: anyNamed('onError'),
)).thenAnswer((Invocation invocation) {
  final namedArgs = invocation.namedArguments;
  final onData = namedArgs[Symbol('onData')] as Function(Photo);
  final onDone = namedArgs[Symbol('onDone')] as Function();
  final onError = namedArgs[Symbol('onError')] as Function(dynamic);

  return Stream<Photo>.fromFuture(
    Future<Photo>.delayed(Duration(milliseconds: 50), () => Photo()),
  ).listen(onData, onDone: onDone, onError: onError, cancelOnError: true);
});
like image 163
Niko Ruotsalainen Avatar answered Mar 06 '23 12:03

Niko Ruotsalainen