Consider the following class:
enum LoginState { loggedOut, loggedIn }
class StreamListener {
final FirebaseAuth _auth;
LoginState _state = LoginState.loggedOut;
LoginState get state => _state;
StreamListener({required FirebaseAuth auth}) : _auth = auth {
_auth.userChanges().listen((user) {
if (user != null) {
_state = LoginState.loggedIn;
} else {
_state = LoginState.loggedOut;
}
});
}
}
I would like to test that when a user login the state changes from loggedOut to loggedIn, see the following test code:
class FakeUser extends Fake implements User {}
@GenerateMocks([FirebaseAuth])
void main() {
StreamController<User?> controller = StreamController<User?>();
final User value = FakeUser();
setUp(() {
controller = StreamController.broadcast();
});
tearDown(() {
controller.close();
});
test('Stream listen test', () {
final MockFirebaseAuth mockAuth = MockFirebaseAuth();
when(mockAuth.userChanges()).thenAnswer((_) => controller.stream);
StreamListener subject = StreamListener(auth: mockAuth);
controller.add(value);
expect(subject.state, LoginState.loggedIn);
});
}
However, due to the async behaviour the login state is still loggedOut. How could I test this properly?