I have a Widget which uses bloc builder to map the different state of widget.
class BodyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<NewsBloc, NewsState>(builder: (context, state) {
return state.map(
.....
);
});
}
....
}
The BodyWidget
is created in a Widget with BlocProvider.
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) =>
getIt<NewsBloc>()..add(const NewsEvent.fetchNewsData()),
child: BodyWidget(),
);
}
....
}
And the NewsBloc is defined as
@injectable
class NewsBloc extends Bloc<NewsEvent, NewsState> {
final GetNews getNews;
NewsBloc({
@required this.getNews,
}) : super(const _Initial());
@override
Stream<NewsState> mapEventToState(
NewsEvent event,
) async* { ... }
}
I am using get_it and injectable for Dependency Injection.
Now I am trying to write a simple widget test for BodyWidget
and I am not so sure how to inject all these dependency in test.
class MockBuildContext extends Mock implements BuildContext {}
class MockNewsBloc extends Mock implements NewsBloc {}
void main() {
ForYouNewsTab _widget;
MockBuildContext _context;
NewsBloc _newsBloc;
Widget makeTestableWidgets({Widget child}) {
return MaterialApp(
home: Scaffold(
// body: BlocProvider(
// create: (_context) => getIt<NewsBloc>(),
// child: child,
// ),
body: child,
),
);
}
setUp(() {
_context = MockBuildContext();
_widget = ForYouNewsTab();
});
test('ForYouNewsTab is sub class of StatelessWidget', () {
expect(_widget, isA<StatelessWidget>());
});
testWidgets('should return sized box for initial state',
(WidgetTester tester) async {
await tester.pumpWidget(makeTestableWidgets(child: _widget));
});
}
I did search in stackoverflow, but could not found a solution that works form me.
I solved my issue by following very basic steps. Not so sure if its the right way. Anyway if anyone ever comes to the same problem, it might help them.
class MainPage extends StatelessWidget {
//added line
final NewsBloc newsBloc;
const MainPage({
Key key,
@required this. newsBloc,
})
@override
Widget build(BuildContext context) {
return BlocProvider(
// changed line
// create: (context) => getIt<NewsBloc>()..add(const NewsEvent.fetchNewsData()),
create: (context) => newsBloc..add(const NewsEvent.fetchNewsData()),
child: BodyWidget(),
);
}
....
}
Now in my test case I can create MockNewsBloc and inject it easily to the MainPage when it is under testing.