Flutter 小部件测试 - 未连接键盘

Kev*_*atz 5 testing flutter

我正在尝试测试我的有状态小部件CheckedTextField

\n\n
class _CheckedTextFieldState extends State<CheckedTextField> {\n  TextEditingController _controller = TextEditingController();\n  bool _checked;\n  String _valueBackup;\n\n  @override\n  void initState() {\n    super.initState();\n    _checked = widget.initialChecked;\n    _controller.text = widget.initialValue;\n    _controller.addListener(invokeCallback);\n  }\n\n  invokeCallback() {\n    widget.callback(_controller.text.trim(), _checked);\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Row(\n      children: <Widget>[\n        Expanded(\n          child: TextField(\n            enabled: _checked,\n            controller: _controller,\n            decoration: widget.decoration,\n          ),\n        ),\n        Checkbox(\n          onChanged: (value) {\n            if (value == false) {\n              _valueBackup = _controller.text;\n              _controller.text = "";\n            }\n            if (value == true) {\n              _controller.text = _valueBackup;\n            }\n            setState(() {\n              _checked = value;\n            });\n            invokeCallback();\n          },\n          value: _checked,\n        ),\n      ],\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我尝试使用以下代码测试小部件时,引擎告诉我首先显示键盘:

\n\n
testWidgets(\'enter text when not checked\', (WidgetTester tester) async {\n  String value = "";\n  bool checked = false;\n  await tester.pumpWidget(\n    wrapMaterial(\n      CheckedTextField(\n        initialValue: value,\n        initialChecked: checked,\n        callback: (_value, _checked) {\n          value = _value;\n          checked = _checked;\n        },\n      ),\n    ),\n  );\n\n  await tester.enterText(find.byType(TextField), "newText");\n\n  expect(value, "newText");\n  expect(checked, isFalse);\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

我已经尝试在输入文本之前手动显示键盘await tester.showKeyboard(find.byType(TextField));,但问题仍然存在。

\n\n

我还编写了一个查找谓词来确保找到 TextField,因此问题似乎出在其他地方。

\n\n

抛出的异常:

\n\n
\xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK \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\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\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following TestFailure object was thrown running a test:\n  Tried to use TestTextInput with no keyboard attached. You must use WidgetTester.showKeyboard() first.\n\nWhen the exception was thrown, this was the stack:\n#0      TestTextInput.updateEditingValue (package:flutter_test/src/test_text_input.dart:133:7)\n#1      TestTextInput.enterText (package:flutter_test/src/test_text_input.dart:170:5)\n#2      WidgetTester.enterText.<anonymous closure> (package:flutter_test/src/widget_tester.dart:875:21)\n<asynchronous suspension>\n#3      WidgetTester.enterText.<anonymous closure> (package:flutter_test/src/widget_tester.dart)\n#6      TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:72:41)\n#7      WidgetTester.enterText (package:flutter_test/src/widget_tester.dart:873:27)\n#8      main.<anonymous closure> (file:///home/kevin/Projekte/Blackout/test/widget/checked_text_field/checked_text_field_test.dart:54:18)\n<asynchronous suspension>\n#9      main.<anonymous closure> (file:///home/kevin/Projekte/Blackout/test/widget/checked_text_field/checked_text_field_test.dart)\n#10     testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:140:29)\n<asynchronous suspension>\n#11     testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart)\n#12     TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:703:19)\n<asynchronous suspension>\n#15     TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:683:14)\n#16     AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:1083:24)\n#17     FakeAsync.run.<anonymous closure>.<anonymous closure> (package:fake_async/fake_async.dart:177:54)\n#22     withClock (package:clock/src/default.dart:46:10)\n#23     FakeAsync.run.<anonymous closure> (package:fake_async/fake_async.dart:177:22)\n#28     FakeAsync.run (package:fake_async/fake_async.dart:177:7)\n#29     AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:1080:15)\n#30     testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:133:24)\n#31     Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:172:27)\n<asynchronous suspension>\n#32     Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart)\n#33     Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:246:15)\n#38     Invoker.waitForOutstandingCallbacks (package:test_api/src/backend/invoker.dart:243:5)\n#39     Declarer.test.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:170:33)\n#44     Declarer.test.<anonymous closure> (package:test_api/src/backend/declarer.dart:169:13)\n#45     Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:400:30)\n(elided 36 frames from class _RawReceivePortImpl, class _Timer, dart:async, dart:async-patch, and package:stack_trace)\n\nThe test description was:\n  enter text when not checked\n\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\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\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\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\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\n
Run Code Online (Sandbox Code Playgroud)\n

小智 0

您需要将 textInput 附加到它。只需使用 await tester.showKeyboard(find.byType(TextField));

testWidgets('enter text when not checked', (WidgetTester tester) async {
  String value = "";
  bool checked = false;
  await tester.pumpWidget(
    wrapMaterial(
      CheckedTextField(
        initialValue: value,
        initialChecked: checked,
        callback: (_value, _checked) {
          value = _value;
          checked = _checked;
        },
      ),
    ),
  );

  await tester.showKeyboard(find.byType(TextField));

  await tester.enterText(find.byType(TextField), "newText");

  expect(value, "newText"); //it's not part of the question but this WILL not change
  expect(checked, isFalse);
});
Run Code Online (Sandbox Code Playgroud)

如果您想检查此 EditableText 的状态,即。控制器、小部件属性、...;

final _focusedEditable = tester.state<EditableTextState>(
        find.descendant(
          of: find.byType(TextField).first,
          matching: find.byType(EditableText),
          matchRoot: true,
        ),
      );
Run Code Online (Sandbox Code Playgroud)

如果您想检查文本输入,请使用 tester.testTextInput,即。键盘可见,客户聆听