Testing Tabbar border on TabBar widget Flutter

Issue

I have a CustomTabBar class which returns a TabBarWidget. So Basic Structure of the CustomTabBar widget is like:

class CustomTabBar extends StatelessWidget {
  ...
  final bool isBottomIndicator;
  ...

  @override
  Widget build(BuildContext context) {
    return TabBar(
      .....
      indicator: BoxDecoration(
        border: isBottomIndicator
            ? Border(
                bottom: BorderSide(
                  color: Theme.of(context).colorScheme.tabbarSelectorColor,
                  width: 3.0,
                ),
              )
            : Border(
                top: BorderSide(
                  color: Theme.of(context).colorScheme.tabbarSelectorColor,
                  width: 3.0,
                ),
              ),
      ),
      ......
    );
  }
} 

The position of the indicator is controller by the variable isBottomIndicator.

Now I am trying to write a testcase for this widget. So Far I have tried this test case:

testWidgets('CustomTabBar with bottom indicator',
      (WidgetTester tester) async {
    final _customTabBar = CustomTabBar(
      tabs: _tabs,
      selectedIndex: _selectedIndex,
      onTap: (_) {},
      isBottomIndicator: true,
    );
    await tester.pumpWidget(makeTestableWidgets(child: _customTabBar));

    final tabBar = find.byType(TabBar).first as TabBar;

    expect(
      tabBar.indicator,
      BoxDecoration(
        border: Border(
          bottom: BorderSide(
            width: 3.0,
          ),
        ),
      ),
    );
  });

The exception I am getting from the compiler is

The following _CastError was thrown running a test:
type '_WidgetTypeFinder' is not a subtype of type 'TabBar' in type cast

I am not sure how can I cast the wiget I found via find.byType()

The following test passes where I check if TabBar is present.

testWidgets('CustomTabBar has a TabBar', (WidgetTester tester) async {
    await tester.pumpWidget(makeTestableWidgets(child: _customTabBar));
    expect(find.byType(TabBar), findsOneWidget);
  });

If you are interested on makeTestableWidgets. This function just provide Material App for the TabBar.

Widget makeTestableWidgets({Widget child}) {
    return MaterialApp(
      home: DefaultTabController(
        length: 1,
        child: Scaffold(
          body: Container(),
          bottomNavigationBar: _customTabBar,
        ),
      ),
    );
  }

Solution

In your testcase, replace the line

final tabBar = find.byType(TabBar).first as TabBar;

with

final tabBar = tester.widget(find.byType(TabBar)) as TabBar;

I have not tested it myself but think it will do the trick.

Answered By – Shiraj

Answer Checked By – Candace Johnson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *