【问题标题】:Flutter widget tests cannot find InputDecoration.errorTextFlutter 小部件测试找不到 InputDecoration.errorText
【发布时间】:2021-02-04 16:22:27
【问题描述】:

注意:这是针对 Flutter Web 应用的。

我正在测试一个 TextField 以显示如果输入无效,则会显示 InputDecoration 上指定的错误文本。

当我运行整个应用程序并手动与之交互时,小部件可以正常工作。

这是我的 TextField 的定义:

TextField(
  key: ValueKey('IntSpinner-TEXT'),
  controller: _controller,
  keyboardType: _keyboardType(),
  inputFormatters: widget.inputFormatters ?? [formatter],
  decoration: InputDecoration(
    border: const OutlineInputBorder(),
    errorText: _validInput ? null : 'Invalid input',
  ),
);

我在 TextField 的控制器上有一个侦听器,它检查新值,并相应地将 _validInput 设置为 true 或 false。

这是我的测试代码:

    testWidgets('should flag invalid values', (WidgetTester tester) async {
      int x;
      await tester.pumpWidget(MaterialApp(
        home: Card(
          child: Column(
            children: [
              IntSpinner( // this widget contains my TextField
                key: ValueKey('IntSpinner'),
                onChanged: (value) => x = value,
              ),
            ],
          ),
        ),
      ));

      // Enter valid text
      await tester.enterText(find.byKey(ValueKey('IntSpinner-TEXT')), '-2200');
      expect(x, equals(-2200));

      // Enter invalid text
      await tester.enterText(find.byKey(ValueKey('IntSpinner-TEXT')), '2-200');
      expect(x, equals(-2200)); // unchanged!!
      
      TextField txt = tester.widget(find.byKey(ValueKey('IntSpinner-TEXT')));
      expect(txt.decoration.errorText, equals('Invalid input'));
    });

我收到此错误:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
  Expected: 'Invalid input'
  Actual: <null>
   Which: not an <Instance of 'String'>

我在调试器中看到了同样的情况—— inputDecoration.errorText 为空。但是当我在浏览器中运行应用程序时,我可以清楚地看到(使用 Flutter Widget Inspector)errorText 已按预期设置(我还看到 TextField 被绘制为 errorText)。

Widget Inspector 输出片段:

从 Flutter 小部件测试中检查 TextField.decoration.errorText 的正确方法是什么?

【问题讨论】:

  • 您的监听器是否正确设置了 _validInput 的 controller.text 初始值为 ""(即,当您未指定初始值且未键入任何内容时)?
  • 是的。我实际上提供了一个有效的初始值。更重要的是,我可以直观地检查正在运行的应用程序,就 errorText 是否可见而言,一切似乎都是正确的。
  • 你能把这个测试作为你的第一个测试吗?我怀疑上面完成的任务是造成这种情况的原因。
  • 完成了,没有区别。仍然为 errorText 返回 null。
  • 是_validInput的值有问题;我添加了一个 print('build:$_validInput');我的 Widget.build() 方法顶部的语句,它总是打印“build:true”。

标签: flutter flutter-web flutter-test


【解决方案1】:

我有一个可行的解决方案。我希望有知识的人来验证它。

在编写测试时设置 _validInput 时不会触发小部件的重建。相反,它似乎要等到我“完成”编辑。我通过将焦点从 TextField 移到另一个 TextField 上来伪造这一点(使用 WidgetTester.showKeyboard(finder))。

所以现在我的测试步骤如下:

      // print('Enter valid text');
      await tester.enterText(find.byKey(ValueKey('IntSpinner-TEXT')), '-2200');
      expect(x, equals(-2200));
      
      // move the focus somewhere else ... anywhere else
      await tester.showKeyboard(find.byKey(Key('FOO')));
      TextField txt = tester.widget(find.byKey(ValueKey('IntSpinner-TEXT')));
      expect(txt.decoration.errorText, isNull);

      // print('Enter invalid text');
      await tester.enterText(find.byKey(ValueKey('IntSpinner-TEXT')), '2-200');
      expect(x, equals(-2200)); // unchanged!!

      // move the focus somewhere else ... anywhere else
      await tester.showKeyboard(find.byKey(Key('FOO')));
      txt = tester.widget(find.byKey(ValueKey('IntSpinner-TEXT')));
      expect(txt.decoration.errorText, equals('Invalid input'));

这让我的测试工作;问题是,为什么 errorText 会显示在正在运行的应用程序上,而没有将焦点移到另一个小部件?

【讨论】:

    猜你喜欢
    • 2022-12-12
    • 2019-02-25
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 2021-02-22
    • 2022-08-03
    • 2021-07-08
    • 2021-07-29
    相关资源
    最近更新 更多