I tried the solutions in here https://github.com/felangel/mocktail/issues/42 but still get error. This is my code:

class MockUserRepository extends Mock implements UserRepository {}
class MockAuthenticationBloc extends MockBloc<AuthenticationEvent, AuthenticationState> implements AuthenticationBloc {}
class FakeAuthenticationEvent extends Fake implements AuthenticationEvent {}
class FakeAuthenticationState extends Fake implements AuthenticationState {}

void main() {
  MockUserRepository mockUserRepository;
  MockAuthenticationBloc mockAuthenticationBloc;

  setUp(() {
    mockUserRepository = MockUserRepository();
    mockAuthenticationBloc = MockAuthenticationBloc();
    registerFallbackValue(FakeAuthenticationEvent());
    registerFallbackValue(FakeAuthenticationState());
  });

  group('Login', () {
    final username = 'someusername';
    final password = 'somepassword';
    final token = 'sometoken';
    final loginError = 'Some error message.';

    blocTest('emits [LoginLoading] when successful',
      build: () {
        when(() => mockUserRepository.authenticate(username: username, password: password)).thenAnswer((_) async => token);
        return LoginBloc(userRepository: mockUserRepository, authenticationBloc: mockAuthenticationBloc);
      },
      act: (bloc) => bloc.add(LoginButtonPressed(username: username, password: password)),
      expect: () => [
        LoginInitial(),
        LoginLoading(),
      ],
    );
  });
}

And this is the error:

Bad state: A test tried to use any or captureAny on a parameter of type AuthenticationState, but registerFallbackValue was not previously called to register a fallback value for AuthenticationState.

To fix, do:

void main() {
  setUpAll(() {
    registerFallbackValue(/* create a dummy instance of `AuthenticationState` */);
  });
}

This instance of AuthenticationState will only be passed around, but never be interacted with. Therefore, if AuthenticationState is a function, it does not have to return a valid object and could throw unconditionally. If you cannot easily create an instance of AuthenticationState, consider defining a Fake:

class MyTypeFake extends Fake implements MyType {}

void main() {
  setUpAll(() {
    registerFallbackValue(MyTypeFake());
  });
}

What did i miss?


Solution 1: R3HP

as said in the docs :

In order to support argument matchers such as any() and captureAny() mocktail has to register default fallback values to return when the argument matchers are used. Out of the box, it automatically handles all primitive types, however, when using argument matchers in place of custom types developers must use registerFallbackValue() to provide a default return value. It is only required to call registerFallbackValue() once per type so it is recommended to place all registerFallbackValue() calls within setUpAll().

basically you can only use any() or captureAny() on String,int,double and other primitive Data Types ,

for using any on a non primitive data type you should register a default value so mocktail knows what to return;

you can create a Fake for ease of use like this

class Food {...}

class Cat {
  bool likes(Food food) {...}
}

class MockCat extends Mock implements Cat {}

class FakeFood extends Fake implements Food {}

void main() {
  setUpAll(() {
    registerFallbackValue(FakeFood());
  });

  test('...', () {
    final cat = MockCat();
    when(() => cat.likes(any()).thenReturn(true);
    ...
  });
}