Flutter:如何测试 Widgets State 类中的方法?

Mil*_*son 7 unit-testing widget flutter

我有一个小部件测试,用于我命名的抽屉DefaultDrawer。我还想测试一下我在里面所做的方法DefaultDrawerState.例如,

class DefaultDrawerState extends State<DefaultDrawer> {

  @override
  Widget build(BuildContext context) {
    // ..build..
  }

  Widget _circleAvatar() {
    // a method I want to test
  }
}
Run Code Online (Sandbox Code Playgroud)

_circleAvatar()flutter_test查找器似乎无法调用我的小部件或其状态中的方法时,如何测试该方法?

下面是我现在的测试文件,没有测试小部件内的方法:

void main() {
  testWidgets('Drawer Test', (WidgetTester tester) async {
    final key = GlobalKey<ScaffoldState>();
    await tester.pumpWidget(
        MaterialApp(home: Scaffold(key: key, drawer: DefaultDrawer())));

    // open drawer
    key.currentState.openDrawer();
    await tester.pump();

    // did drawer open?
    final drawerFinder = find.byType(Drawer);
    expect(drawerFinder, findsOneWidget);
  });
}
Run Code Online (Sandbox Code Playgroud)

Oma*_*att 0

为了能够测试 Widget,您需要使用WidgetTester.pumpWidget(Widget). 让`SampleWidget

\n
class SampleWidget {\n  Widget getWidget() {\n    return Container(\n      key: Key(\'SampleWidget\'),\n      color: Colors.green,\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

...并在测试中,直接调用 Widget 来widgetTester.pumpWidget(SampleWidget().getWidget());渲染它以进行测试。

\n
void main() {\n  IntegrationTestWidgetsFlutterBinding.ensureInitialized();\n  \n  testWidgets("Test Widget", (WidgetTester widgetTester) async {\n    bool found = false;\n    await widgetTester.pumpWidget(SampleWidget().getWidget());\n    widgetTester.allWidgets.forEach((Widget element) {\n      if(element.key.toString().contains(\'SampleWidget\')){\n        debugPrint(\'Found Sample Widget!\');\n        found = true;\n      }\n    });\n    expect(found, true);\n  });\n}\n
Run Code Online (Sandbox Code Playgroud)\n

测试应该能够找到包含指定键的小部件元素。

\n

然而,WidgetTester 上的一些 Widget 需要 MaterialApp 作为其父级。此小部件的一个示例是文本 - 它需要方向性,并且可以通过使用 MaterialApp 或 WidgetsApp 小部件找到方向性。在测试中渲染没有 MaterialApp 的 Text Widget 将失败。将抛出此错误。

\n
\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY WIDGETS LIBRARY \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following assertion was thrown building Text("Demo Widget"):\nNo Directionality widget found.\nRichText widgets require a Directionality widget ancestor.\nThe specific widget that could not find a Directionality ancestor\nwas:\n  RichText\nThe ownership chain for the affected widget is: "RichText \xe2\x86\x90 Text\n  \xe2\x86\x90 Center \xe2\x86\x90 ColoredBox \xe2\x86\x90 Container-[<\'SampleWidget\'>] \xe2\x86\x90\n  RepaintBoundary \xe2\x86\x90 [root]"\nTypically, the Directionality widget is introduced by the\nMaterialApp or WidgetsApp widget at the top of your application\nwidget tree. It determines the ambient reading direction and is\nused, for example, to determine how to lay out text, how to\ninterpret "start" and "end" values, and to resolve\nEdgeInsetsDirectional, AlignmentDirectional, and other\n*Directional objects.\n
Run Code Online (Sandbox Code Playgroud)\n

作为此用例的解决方法,您可以使用 MaterialApp 包装您的 Widget。

\n
\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY WIDGETS LIBRARY \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following assertion was thrown building Text("Demo Widget"):\nNo Directionality widget found.\nRichText widgets require a Directionality widget ancestor.\nThe specific widget that could not find a Directionality ancestor\nwas:\n  RichText\nThe ownership chain for the affected widget is: "RichText \xe2\x86\x90 Text\n  \xe2\x86\x90 Center \xe2\x86\x90 ColoredBox \xe2\x86\x90 Container-[<\'SampleWidget\'>] \xe2\x86\x90\n  RepaintBoundary \xe2\x86\x90 [root]"\nTypically, the Directionality widget is introduced by the\nMaterialApp or WidgetsApp widget at the top of your application\nwidget tree. It determines the ambient reading direction and is\nused, for example, to determine how to lay out text, how to\ninterpret "start" and "end" values, and to resolve\nEdgeInsetsDirectional, AlignmentDirectional, and other\n*Directional objects.\n
Run Code Online (Sandbox Code Playgroud)\n