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()
andcaptureAny()
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 useregisterFallbackValue()
to provide a default return value. It is only required to callregisterFallbackValue()
once per type so it is recommended to place allregisterFallbackValue()
calls withinsetUpAll()
.
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);
...
});
}