Reputation: 2018
I am trying to learn bloc and I am writing simple unit tests. I am trying to test the auth events but I am facing the error below. Inside my app when I trigger an event, I don't get any errors and everything seems to work fine, so why am I getting error here? Am I missing something, could anyone advise?
class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> {
final AuthenticationRepository _authRepository;
late StreamSubscription<AuthStatus> _authSubscription;
AuthenticationBloc(
{required AuthenticationRepository authenticationRepository})
: _authRepository = authenticationRepository,
super(const AuthenticationState()) {
on<AuthStateChanged>(_onAuthStatusChanged);
on<AuthenticationLogoutRequested>(_onLogoutRequested);
_authSubscription = _authRepository.status
.listen((status) => add(AuthStateChanged(authStatus: status)));
}
enum AuthStatus { unknown, authenticated, unauthenticated }
class AuthenticationRepository {
final _controller = StreamController<AuthStatus>();
Stream<AuthStatus> get status => _controller.stream;
Future<void> logIn({
required String username,
required String password,
}) async {
await Future.delayed(
const Duration(milliseconds: 300),
() => _controller.add(AuthStatus.authenticated),
);
}
void logOut() {
_controller.add(AuthStatus.unauthenticated);
}
void dispose() => _controller.close();
}
class AuthenticationState extends Equatable {
final AuthStatus status;
final User? user;
const AuthenticationState({this.status = AuthStatus.unknown, this.user});
@override
List<Object?> get props => [user, status];
}
void main() {
late AuthenticationBloc authenticationBloc;
MockAuthenticationRepository authenticationRepository = MockAuthenticationRepository();
setUp((){
authenticationBloc = AuthenticationBloc(authenticationRepository: authenticationRepository);
});
group('AuthenticationEvent', () {
group('Auth status changes', () {
test('User is unknown', () {
expect(authenticationBloc.state.status, AuthStatus.unknown);
});
test('User is authorized', () {
authenticationBloc.add(AuthStateChanged(authStatus: AuthStatus.authenticated));
expect(authenticationBloc.state.status, AuthStatus.authenticated);
});
test('User is unauthorized', () {
authenticationBloc.add(AuthStateChanged(authStatus: AuthStatus.unauthenticated));
expect(authenticationBloc.state.status, AuthStatus.unknown);
});
});
});
}
Upvotes: 3
Views: 1714
Reputation: 196
It is most likely that you have not created a stub for a function in your mock class. This is generally the cause of the NULL return. This can be achieved by using when() from the mockito package. https://pub.dev/packages/mockito.
Also there is a bloc testing package that may be useful to look into. https://pub.dev/packages/bloc_test
Below is an example of how I implemented it. Hope this helps.
blocTest<ValidateUserBloc, ValidateUserState>('Validate User - Success',
build: () {
when(mockSettingsRepo.validateUser(url, authCode)).thenAnswer(
(_) async => User(
success: true, valid: true, url: url, authCode: authCode));
return validateUserBloc;
},
seed: () => ValidateUserState(user: User(url: url, authCode: authCode)),
act: (bloc) => bloc.add(ValidateUserAuthoriseEvent()),
expect: () => <ValidateUserState>[
ValidateUserState(
status: ValidUserStatus.success,
user: User(
success: true, valid: true, url: url, authCode: authCode))
]);
Upvotes: 4