felangel / mocktail

A mock library for Dart inspired by mockito
https://pub.dev/packages/mocktail
MIT License
588 stars 80 forks source link

Calling `when` consecutively doesn't stub mocks #206

Closed pongloongyeat closed 10 months ago

pongloongyeat commented 10 months ago

Describe the bug Not sure if this is the underlying issue but it seems like calling two stubbed methods one after the other causes the example below to throw type 'Null' is not a subtype of type 'Future<void>'.

To Reproduce

import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';

class SomeBloc extends Bloc<int, int> {
  SomeBloc(
    super.initialState, {
    required this.repository1,
    required this.repository2,
  }) {
    on((event, emit) async {
      switch (event) {
        case 1:
          await repository1.call();
          await repository2.call(); // This line is throwing during tests
          emit(state);
        default:
          return;
      }
    });
  }

  final Repository1 repository1;
  final Repository2 repository2;
}

abstract class BaseRepository {
  Future<void> call() => Future.delayed(const Duration(milliseconds: 100));
}

class Repository1 extends BaseRepository {}

class Repository2 extends BaseRepository {}

class MockRepository1 extends Mock implements Repository1 {}

class MockRepository2 extends Mock implements Repository2 {}

void main() {
  late MockRepository1 repository1;
  late MockRepository2 repository2;
  late SomeBloc bloc;

  setUp(() {
    repository1 = MockRepository1();
    repository2 = MockRepository2();
    bloc = SomeBloc(0, repository1: repository1, repository2: repository2);
  });

  tearDown(() {
    reset(repository1);
    reset(repository2);
  });

  group('SomeBloc', () {
    test('', () {
      when(repository1.call).thenAnswer((_) async {});
      when(repository2.call).thenAnswer((_) async {});

      testBloc(
        build: () => bloc,
        act: (bloc) => bloc.add(1),
        expect: () => [0],
      );
    });
  });
}

Expected behavior It shouldn't throw

Additional context mocktail: 1.0.0

pongloongyeat commented 10 months ago

To add, seems like doing this works but this would effectively make my setUps useless and I'd have to write this at the start of a test each time.

  group('SomeBloc', () {

+  final repository1 = MockRepository1();
+  final repository2 = MockRepository2();

+  final bloc = SomeBloc(0, repository1: repository1, repository2: repository2);

    test('', () {
      when(repository1.call).thenAnswer((_) async {});
      when(repository2.call).thenAnswer((_) async {});

      testBloc(
        build: () => bloc,
        act: (bloc) => bloc.add(1),
        expect: () => [0],
      );
    });
  });
pongloongyeat commented 10 months ago

Closing as issue is not related to mocktail but rather the incorrect use of bloc_test (should've used blocTest instead of testBloc).