Flutter Cubit Testing States - flutter

Trying to write tests for a cubit in flutter. When I run my code, everything works fine, but the tests are causing me issues.
When I run this, I get an error:
> type 'Null' is not a subtype of type 'Future<Fact>'
> MockFactRepository.fetchFact
/test/fact_cubit_test.dart
group(
'Get Fact',
() {
const fact = Fact(text: 'This is a fact');
blocTest(
'emits [FactCubit.initial, .loading, .loaded] when successful',
build: () {
when(mockFactRepository.fetchFact()).thenAnswer((_) async => fact);
return FactCubit(mockFactRepository);
},
act: (FactCubit cubit) => cubit.getFact(),
expect: () => [
FactState.initial().runtimeType,
FactState.loading().runtimeType,
FactState.loaded(fact).runtimeType,
],
);
},
);

Related

Flutter Bloc Test verify/running a function after get result

I try to test bloc (AuthBloc) which running "logout" when getLocalToken is failed and I get this error.
How can I verify/running logout after I get result ServerException on my bloctest.
Please Help.
Thanks before.
My Bloc :
on<AppStarted>((event, emit) async {
final token = await getLocalToken(const Params(needValidation: true));
token.fold(
(failure) {
logout(NoParams());
emit(AuthNotAuthenticated());
},
(auth) => emit(AuthAuthenticated()),
);
});
Here My Test Code :
blocTest<AuthBloc, AuthState>(
'should emit [AuthNotAuthenticated] when token / input is invalid',
build: () {
when(mockGetLocalToken(any))
.thenAnswer((_) async => Left(ServerFailure()));
return bloc;
},
act: (blc) => blc.add(AppStarted()),
expect: () { return <AuthState>[AuthNotAuthenticated()];},
);
Error :
00:03 +2 -1: AppStarted should emit [AuthNotAuthenticated] when token / input is invalid [E]
MissingStubError: 'call'
No stub was found which matches the arguments of this method call:
call(NoParams())
Add a stub for this method using Mockito's 'when' API, or generate the MockLogout mock with a MockSpec with 'returnNullOnMissingStub: true'
Expected: [AuthNotAuthenticated:AuthNotAuthenticated()]
Actual: []
Which: at location [0] is [] which shorter than expected
==== diff ========================================
[[-AuthNotAuthenticated()-]]
==== end diff ====================================

Flutter blocTest Missing type arguments for generic function 'blocTest<B extends BlocBase<State>, State>'

When following the bloc test documentation, I created the following blocTest;
blocTest('should do something',
build: () => SignInBloc(signIn: mockSignIn),
act: (bloc) => bloc.add(const OnEmailChanged(email: 'test')));
However I get the intellisense error;
Missing type arguments for generic function 'blocTest<B extends BlocBase<State>, State>'.
And the (bloc) provided in the add is of type Object?.
To fix the issue you have to tell the blocTest what types to expect.
blocTest<SignInBloc, SignInState>('should do something',
build: () => SignInBloc(signIn: mockSignIn),
act: (bloc) => bloc.add(const OnEmailChanged(email: 'test')));
});

Updating cloud firestore data in a map from flutter

This is my code:
child: new GridView.count(
crossAxisCount: 3,
children: snapshot.data.documents.map<Widget>((DocumentSnapshot document) {
return new MoodButton(
iconData: (IconData(document.data()['ref'],fontFamily: 'MaterialIcons')),
onTap: () =>
document.data()[document.data()['ref']].updateData({"display": true}),
);
}).toList(),
)
I am trying to update the value of display for the icon that has been clicked on from false to true.
The issue is with the line document.data()[document.data()['ref']].updateData({"Display": true}),. I am not sure how to update the data for the specific icon that has been clicked on.
The error I am getting is:
The method 'updateData' was called on null.
Receiver: null
Tried calling: updateData(_LinkedHashMap len:1)
Any help would be appreciated!
I figured it out following this tutorial.
I replaced onTap: () => document.data()[document.data()['ref']].updateData({"display": true}), with onTap: () => updateData((document.data()['name']), {'display' : true}),
Then added
updateData(selectedDoc, newValues) {
print(selectedDoc);
print(newValues);
FirebaseFirestore.instance
.collection('icons')
.doc(selectedDoc)
.update(newValues)
.catchError((e) {
print(e);
});
}

Why one of my state is not triggered during my test

I followed Reso code youtube to create a small weather app, but I used the latest bloc library and flutter_bloc 4.0 also.
Base App: https://www.youtube.com/watch?v=hTExlt1nJZI&list=PLB6lc7nQ1n4jCBkrirvVGr5b8rC95VAQ5&index=7
BLoc Test: https://www.youtube.com/watch?v=S6jFBiiP0Mc&list=PLB6lc7nQ1n4jCBkrirvVGr5b8rC95VAQ5&index=8
The first 2 tests are working. For example, the below one does not give me any error:
test(
'NEWER WAY BUT lONG-WINDED emits [WeatherLoading, WeatherLoaded] when successful',
() {
when(mockWeatherRepository.fetchWeather(any))
.thenAnswer((_) async => weather);
final bloc = WeatherBloc(mockWeatherRepository);
bloc.add(GetWeather('London'));
emitsExactly(bloc, [
WeatherInitial(),
WeatherLoading(),
WeatherLoaded(weather),
]);
});
For some reason, that test below does not trigger the WeatherInitial.
blocTest(
'emits [WeatherLoading, WeatherLoaded] when successful',
build: () async {
when(mockWeatherRepository.fetchWeather(any))
.thenAnswer((_) async => weather);
return WeatherBloc(mockWeatherRepository);
},
act: (bloc) => bloc.add(GetWeather('London')),
expect: [
WeatherInitial(),
WeatherLoading(),
WeatherLoaded(weather),
],
);
The error is:
ERROR: Expected: [
WeatherInitial:WeatherInitial,
WeatherLoading:WeatherLoading,
WeatherLoaded:WeatherLoaded
]
Actual: [WeatherLoading:WeatherLoading, WeatherLoaded:WeatherLoaded]
Which: was WeatherLoading:<WeatherLoading> instead of WeatherInitial:<WeatherInitial> at location [0]
Do you have any clue why?
This behaviour is correct according to the official bloc_test library:
skip is an optional int which can be used to skip any number of states.
The default value is 1 which skips the initialState of the bloc.
skip can be overridden to include the initialState by setting skip to 0.
So if you want to include your "InitialState" just ,set the "skip" value to 0 :
.
.
.
skip: 0,
expect: [
WeatherInitial(),
WeatherLoading(),
WeatherLoaded(weather),
],

Test bloc test with parameter failed

So, I have using this bloc_test library version bloc_test: ^5.0.0.
Previously I test bloc with this code and work fine
test(
'should emit [RegisterLoadingState,RegisterLoadedState] when RegisterWithPassword is successful',
() async {
setUpSuccessfulValidateRegister();
setUpSuccessfulRegister();
final expected = [
RegisterInitialState(),
RegisterLoadingState(),
RegisterLoadedState(account: customer),
];
expectLater(bloc, emitsInOrder(expected));
bloc.add(RegisterWithPasswordEvent(
name: nameTest,
email: emailTest,
password: passwordTest,
retypedPassword: retypedPasswordTest,
));
});
Currently I change it with using bloc_test package and the test failed
blocTest(
'should emit [RegisterLoadingState,RegisterLoadedState] when RegisterWithPassword is successful',
build: () async {
setUpSuccessfulValidateRegister();
setUpSuccessfulRegister();
return bloc;
},
act: (bloc) => bloc.add(RegisterWithPasswordEvent(
name: nameTest,
email: emailTest,
password: passwordTest,
retypedPassword: retypedPasswordTest,
)),
expect: [
RegisterLoadingState(),
RegisterLoadedState(account: customer),
],
);
Here is the error in test
Expected: [
RegisterLoadingState:RegisterLoadingState,
RegisterLoadedState:RegisterLoadedState
]
Actual: [
RegisterLoadingState:RegisterLoadingState,
RegisterLoadedState:RegisterLoadedState
]
Which: was RegisterLoadedState:<RegisterLoadedState> instead of RegisterLoadedState:<RegisterLoadedState> at location [1]
package:test_api expect
package:bloc_test/src/bloc_test.dart 124:25 blocTest.<fn>
the error gone if I removed the equatable in state with account parameter. Anyone know why this test works on the first code and failed with bloc_test packages?