I am attempting to test for specific values being emitted using the BloC pattern and bloc_test. Currently, I am able to produce a passing test when I am expecting failure. bloc_test must only check for the Type of states emitted rather than specific values. Is there a way using the bloc_test package to test for specific values of our emitted states?
group('[NewsArticleBloc]', () {
NewsArticleBloc sut;
MockNewsRepo mockNewsRepo;
setUp(() {
mockNewsRepo = new MockNewsRepo();
sut = NewsArticleBloc(newsRepo: mockNewsRepo);
});
tearDown(() => sut.close());
blocTest(
'Next state check',
build: () => sut,
act: (bloc) {
when(mockNewsRepo.getTopHeadlines())
.thenAnswer((_) => Future.value([Article(author: 'Josh')]));
bloc.add(GetTopHeadlines());
},
expect: [
TopHeadlines(topHeadlines: [Article(author: 'Micheal')])
//Expecting failure here ^
],
);
});
If you are happy to use the prerelease version: 8.0.0-nullsafety.0
, you can pass an expected state into expect
in blocTest
, or you can pass a Matcher
like in a regular Dart/Flutter test:
// note expect now requires a function that produces a list
expect: () => [
TypeMatcher<TopHeadlines>(),
]
This will succeed if the first state emitted has a type: TopHeadlines
. If you want to verify some properties of the state in addition to its type, you can also use:
expect: () => [
TypeMatcher<TopHeadlines>()
.having((headlines) => headlines.topHeadlines, 'topHeadlines', hasLength(1))
.having((headlines) => headlines.otherProperty, 'otherProperty', isNotNull)
]
If you cannot use prerelease versions in your app, Bloc
extends Stream
, so you can use regular stream testing methods to verify the correct behaviour:
final bloc = ...
final firstStateEmitted = bloc.skip(1).first; // skip initialState then return the next state
expect(firstStateEmitted, isA<TopHeadlines>());
expect(firstStateEmitted.someProperty, isNotNull);