Sometimes we need to test that a widget is doing a particular thing based on a provided parameter, or something similar. We can do this by using tester.widget and TypeMatcher's having() function.
Let's say we have a custom app bar that, using package:badges, should show a badge on the leading widget (which shows if there is a drawer) if the int badgeCount passed to it is greater than zero. Simply testing for the existence of the Badge widget isn't correct, because Badge is always being built - we need to test if the badge's showBadge property is false. We'd write our test like so:
import 'package:badges/badges.dart';
import 'package:flutter/material.dart' hide Badge;
import 'package:flutter_test/flutter_test.dart';
import 'package:my_package/src/widgets/custom_app_bar.dart';
void main () {
testWidgets('Get widget property', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
appBar: CustomAppBar(
title: Text('AppBar'),
badgeCount: 0,
),
drawer: Drawer(),
),
),
);
final widget = tester.widget(find.byType(CustomAppBar));
expect(widget, isA<CustomAppBar>().having((p) => p.showBadge, 'showBadge', false);
});
}Breakdown:
-
Instead of finding our app bar by directly calling
find(likefinal widget = find.byType(CustomAppBar)), we calltester.widget(), and do ourfindcall inside it. -
We can then
expectthat:A. our widget is of the type we expect it to be by using
isA<CustomAppBar>(), which is aTypeMatcher<T>.B. our widget has the property we expect. We must specify the following three things:
- we reference the
showBadgeproperty itself by callingp.showBadge - we provide the name of the property as a String (this must match the property referenced immediately prior), which in this case is
'showBadge'. - we provide the actual value that we expect the property to be, which in our case is
false.
- we reference the
Credit to Remi on this StackOverflow answer.