flutter_test 是否支持测试 'leaf' 小部件?
Does flutter_test support testing 'leaf' widgets?
假设我创建了一个简单的小部件,例如:
class RightArrowButton extends StatelessWidget {
const RightArrowButton({VoidCallback onPressed})
: this._onPressed = onPressed;
final VoidCallback _onPressed;
@override
Widget build(BuildContext context) {
return IconButton(
visualDensity: VisualDensity.compact,
onPressed: _onPressed,
icon: _buildIcon(iconData()),
);
}
/// Overrride to set a different icon.
IconData iconData() => Icons.play_arrow;
Widget _buildIcon(IconData icon) => Icon(icon, color: Colors.blue);
}
进一步假设我希望对这个小部件进行单元测试。我知道,这是一个非常简单的小部件,但我可能首先尝试使用 TDD 来编写小部件。无论如何,我可以将这个概念应用到更复杂的小部件上。
在这种情况下,测试将非常简单:构建小部件,向其传递一个 onPressed 函数,可以检查该函数的副作用以验证当有人点击小部件时确实调用了 onPressed 方法。
示例测试代码:
void main() {
testWidgets('RightArrowButton', (WidgetTester tester) async {
int counter = 0;
await tester.pumpWidget(RightArrowButton(
onPressed: () => counter++,
));
expect(0, equals(counter));
var button = find.byType(IconButton);
await tester.tap(button);
expect(1, equals(counter));
});
}
但是,当我这样做时,出现以下错误:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building IconButton(Icon, padding: EdgeInsets.all(8.0), dirty):
No Material widget found.
IconButton widgets require a Material widget ancestor.
我在阅读这个 SO 问题后理解错误:
那么 -- 有没有办法按照我想要的方式对小部件进行单元测试?或者我是否被迫测试整个小部件组合以获得有效的 Material 小部件祖先(这更像是一个小型集成测试)?
我找到了一个有效的解决方案。 Flutter 专家,以下方法是实现我隔离测试单个小部件的目标的唯一或最佳方法吗?
void main() {
testWidgets('arrow test', (WidgetTester tester) async {
int counter = 0;
// must include Card to get Material;
// must include MaterialApp to get Directionality
await tester.pumpWidget(MaterialApp(
home: Card(
child: RightArrowButton(
onPressed: () => counter++,
),
),
));
await tester.tap(find.byType(RightArrowButton));
expect(1, equals(counter));
});
}
假设我创建了一个简单的小部件,例如:
class RightArrowButton extends StatelessWidget {
const RightArrowButton({VoidCallback onPressed})
: this._onPressed = onPressed;
final VoidCallback _onPressed;
@override
Widget build(BuildContext context) {
return IconButton(
visualDensity: VisualDensity.compact,
onPressed: _onPressed,
icon: _buildIcon(iconData()),
);
}
/// Overrride to set a different icon.
IconData iconData() => Icons.play_arrow;
Widget _buildIcon(IconData icon) => Icon(icon, color: Colors.blue);
}
进一步假设我希望对这个小部件进行单元测试。我知道,这是一个非常简单的小部件,但我可能首先尝试使用 TDD 来编写小部件。无论如何,我可以将这个概念应用到更复杂的小部件上。
在这种情况下,测试将非常简单:构建小部件,向其传递一个 onPressed 函数,可以检查该函数的副作用以验证当有人点击小部件时确实调用了 onPressed 方法。
示例测试代码:
void main() {
testWidgets('RightArrowButton', (WidgetTester tester) async {
int counter = 0;
await tester.pumpWidget(RightArrowButton(
onPressed: () => counter++,
));
expect(0, equals(counter));
var button = find.byType(IconButton);
await tester.tap(button);
expect(1, equals(counter));
});
}
但是,当我这样做时,出现以下错误:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building IconButton(Icon, padding: EdgeInsets.all(8.0), dirty):
No Material widget found.
IconButton widgets require a Material widget ancestor.
我在阅读这个 SO 问题后理解错误:
那么 -- 有没有办法按照我想要的方式对小部件进行单元测试?或者我是否被迫测试整个小部件组合以获得有效的 Material 小部件祖先(这更像是一个小型集成测试)?
我找到了一个有效的解决方案。 Flutter 专家,以下方法是实现我隔离测试单个小部件的目标的唯一或最佳方法吗?
void main() {
testWidgets('arrow test', (WidgetTester tester) async {
int counter = 0;
// must include Card to get Material;
// must include MaterialApp to get Directionality
await tester.pumpWidget(MaterialApp(
home: Card(
child: RightArrowButton(
onPressed: () => counter++,
),
),
));
await tester.tap(find.byType(RightArrowButton));
expect(1, equals(counter));
});
}