dart-lang / mockito

Mockito-inspired mock library for Dart
https://pub.dev/packages/mockito
Apache License 2.0
636 stars 163 forks source link

Bloc was not initialized in Widget test cases #627

Open GowthamanRavichandran3 opened 1 year ago

GowthamanRavichandran3 commented 1 year ago

I utilized Container and Text widgets in Flutter to create a basic example, and also incorporated a test case for my sample. However, during the test run(widget test case), I encountered a null exception as the bloc was not initialized. I have included my sample for your convenience. Is there a solution to address this issue?

Main.dart file

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:widget_test_case/bloc/resize_bloc.dart';

void main() => runApp(BlocProvider<ResizeBloc>(
      create: (c) => ResizeBloc(),
      child: MyApp(),
    ));

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: BlocBuilder<ResizeBloc, ResizeState>(builder: (context, state) {
          if (state is SelectinState) {
            return Builder(builder: (c) {
              return Center(
                child: GestureDetector(
                    onTap: () {
                      BlocProvider.of<ResizeBloc>(context).add(DummyEvent());
                    },
                    child: Text('State: ${state.items}')),
              );
            });
          }
          return GestureDetector(
            onTap: () {
              BlocProvider.of<ResizeBloc>(context).isSelected.value++;
              BlocProvider.of<ResizeBloc>(context).add(SelectinEvent('items'));
            },
            child: ValueListenableBuilder(
              valueListenable: BlocProvider.of<ResizeBloc>(context).isSelected,
              builder: (context, value, child) => Center(
                child: Column(
                  children: [
                    Container(
                      color: Colors.red,
                      width: 100,
                      height: 100,
                    ),
                    Text(
                        '${BlocProvider.of<ResizeBloc>(context).isSelected.value}')
                  ],
                ),
              ),
            ),
          );
        }),
      ),
    );
  }
}

Test case

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:widget_test_case/bloc/resize_bloc.dart';
import 'package:widget_test_case/main.dart';

class TestBlocMock extends Mock implements ResizeBloc {}

void main() {
  ResizeBloc testBloc = TestBlocMock();

  group('description', () {
    testWidgets('Test', (WidgetTester tester) async {
      when(testBloc.stream).thenAnswer(
        (_) => Stream.fromIterable(
          [ResizeInitial()],
        ),
      );

      await tester.pumpWidget(
          BlocProvider<ResizeBloc>(create: (c) => testBloc, child: MyApp()));
      expect(find.text('State: itmes'), findsNWidgets(0));
    });
  });
}
srawlins commented 1 year ago

Questions like this are best asked on a user forum like StackOverflow or the Flutter Discord server. They have more eyes than just the maintainers to look.

yanok commented 1 year ago
class TestBlocMock extends Mock implements ResizeBloc {}

This is a problem (it might be the problem you are facing, but can't tell for sure, there might be others as well). I don't really know what this ResizeBloc is, but unless it has a very specific API (all methods taking all nullable arguments and returning a nullable result), this way of using Mockito won't work in Dart >= 2.12. You have to use the code generator instead.

@srawlins @natebosch Should we update the docs and scrap all the examples without using codegen?

srawlins commented 1 year ago

Should we update the docs and scrap all the examples without using codegen?

Yes.