Hello
I would like to understand a little bit how can i use verify
while testing a bloc. I wasn't able to find any example around and all my attempt have failed, leaving me no other options that put my verify
checks into the tearDown
statement which of course is not optimal.
The issue I encounter is basically that when the test runs, the verify
method have been called before mapEventToState
resulting in make my test fail.
auth_bloc.dart
import 'package:bloc/bloc.dart';
import 'package:checkin/src/blocs/auth/auth_event.dart';
import 'package:checkin/src/blocs/auth/auth_state.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:meta/meta.dart';
class AuthBloc extends Bloc<AuthEvent, AuthState> {
final FirebaseAuth auth;
AuthBloc({
@required this.auth
});
@override
AuthState get initialState => AuthUninitialized();
@override
Stream<AuthState> mapEventToState(AuthState currentState, AuthEvent event) async* {
/*
...
*/
if (event is LoggedOut) {
this.auth.signOut();
yield AuthUnauthenticated();
}
}
}
auth_bloc_test.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:mockito/mockito.dart';
import 'package:checkin/src/blocs/auth/bloc.dart';
import 'package:test/test.dart';
class MockFirebaseAuth extends Mock implements FirebaseAuth {}
class MockFirebaseUser extends Mock implements FirebaseUser {}
void main() {
group('AuthBloc', () {
AuthBloc authBloc;
MockFirebaseAuth firebaseAuth;
setUp(() {
firebaseAuth = MockFirebaseAuth();
authBloc = AuthBloc(auth: firebaseAuth);
});
group('dispatch LoggedOut', () {
setUp(() {
authBloc.dispatch(LoggedOut());
});
//@TODO: not a good solution
tearDown(() {
verify(firebaseAuth.signOut()).called(1);
});
test("the final state should be AuthAuthenticated and pass the current user", () {
final expectedState = [
AuthUninitialized(),
AuthUnauthenticated(),
];
expectLater(
authBloc.state,
emitsInOrder(expectedState),
);
});
});
});
}
Hey @nerder 馃憢
Great question! You can do the verification in the then
of the expectLater
like:
expectLater(authBloc.state, emitsInOrder(expectedState)).then(() {
verify...
});
You can check out a todos app that is fully tested at the flutter_architecture_samples for more details.
Hope that helps! 馃憤
Amazing! Thank you so much for the fast reply and for this library, it makes coding with Blocs SO smooth!
Hey @nerder 馃憢
Great question! You can do the verification in the
then
of theexpectLater
like:expectLater(authBloc.state, emitsInOrder(expectedState)).then(() { verify... });
You can check out a todos app that is fully tested at the flutter_architecture_samples for more details.
Hope that helps! 馃憤
then()
waits for a FutureOr<T>
so you need to set the returning type <T>
, in this case, <void>
. And you need to declare the callback param, so you need to add, at least _
:
expectLater(authBloc.state, emitsInOrder(expectedState)).then<void>((_) => verify(repository.foo()).called(1));
Can be pretty obvious but I spent some time to figure it out, helping others to do not.
Most helpful comment
Amazing! Thank you so much for the fast reply and for this library, it makes coding with Blocs SO smooth!