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 ourfind
call inside it. -
We can then
expect
that: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
showBadge
property 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.