Describe the bug
Error on mock the bloc to test widgets. The tests were written on a version pre 1.0.0 of the bloc.
To Reproduce
Here an example of code:
class MockHintBloc extends Mock implements HintBloc {}
HintBloc bloc;
void main() {
BehaviorSubject<HintState> hintStream;
setUp(() {
bloc = MockHintBloc();
hintStream = BehaviorSubject<HintState>();
when(bloc.state).thenAnswer(
(_) => hintStream.value,
);
});
tearDown(() {
hintStream.close();
});
testWidgets('Test state HintState.initial', (tester) async {
hintStream.add(HintState.initial());
await _createWidget(tester);
expect(find.byType(SizedBox), findsOneWidget);
});
}
Future<void> _createWidget(
WidgetTester tester,
) async {
await tester.pumpWidget(
PlatformApp(
localizationsDelegates: const [
AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [Locale('pt', 'BR')],
home: BlocProvider<HintBloc>(
create: (context) => bloc,
child: const HintWidget(),
),
),
);
await tester.pump();
}
Expected behavior
I try to change the test to:
class MockHintBloc extends MockBloc<HintEvent, HintState> implements HintBloc {}
HintBloc bloc;
void main() {
setUp(() {
bloc = MockHintBloc();
});
testWidgets('Test state HintState.initial', (tester) async {
whenListen(bloc, Stream.fromIterable([HintState.initial()]));
await _createWidget(tester);
expect(find.byType(SizedBox), findsOneWidget);
});
}
Future<void> _createWidget(
WidgetTester tester,
) async {
await tester.pumpWidget(
PlatformApp(
localizationsDelegates: const [
AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [Locale('pt', 'BR')],
home: BlocProvider<HintBloc>(
create: (context) => bloc,
child: const HintWidget(),
),
),
);
await tester.pump();
}
But the state is null on BlocBuilder of my widget.
What is the correct way to mock the bloc to achieve a determinate state on BlocBuilder?
The test ran with the following code:
class MockHintBloc extends MockBloc<HintEvent, HintState> implements HintBloc {}
HintBloc bloc;
void main() {
BehaviorSubject<HintState> hintStream;
setUp(() {
bloc = MockHintBloc();
hintStream = BehaviorSubject<HintState>();
when(bloc.state).thenAnswer(
(_) => hintStream.value,
);
});
tearDown(() {
hintStream.close();
});
testWidgets('Test state HintState.initial', (tester) async {
final state = HintState.initial();
hintStream.add(state);
await _createWidget(tester);
expect(find.byType(SizedBox), findsOneWidget);
});
}
Future<void> _createWidget(
WidgetTester tester,
) async {
await tester.pumpWidget(
PlatformApp(
localizationsDelegates: const [
AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [Locale('pt', 'BR')],
home: BlocProvider<HintBloc>(
create: (context) => bloc,
child: const HintWidget(),
),
),
);
await tester.pump();
}
Is there a better way?
Hi @mateusfsilva 馃憢
Thanks for opening an issue!
I'm glad you managed to get everything working but I think you should be able to simplify your test even further by refactoring your test to
class MockHintBloc extends MockBloc<HintEvent, HintState> implements HintBloc {}
void main() {
HintBloc bloc;
setUp(() {
bloc = MockHintBloc();
});
tearDown(() {
bloc.close();
});
testWidgets('Test state HintState.initial', (tester) async {
when(bloc.state).thenReturn(HintState.initial());
await _createWidget(tester);
expect(find.byType(SizedBox), findsOneWidget);
});
}
Future<void> _createWidget(
WidgetTester tester,
) async {
await tester.pumpWidget(
PlatformApp(
localizationsDelegates: const [
AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [Locale('pt', 'BR')],
home: BlocProvider<HintBloc>.value(
value: bloc,
child: const HintWidget(),
),
),
);
await tester.pump();
}
Let me know if that helps 馃憤
Yes, that helps.
Thanks
Most helpful comment
Yes, that helps.
Thanks