Flutter - 如何在widget测试中获取Text widget

36

我正在尝试在Flutter中创建一个简单的小部件测试。我有一个自定义小部件,它接收一些值,组合成一个字符串并显示一个包含该字符串的Text。我已经成功创建了这个小部件并使其工作,但是我无法读取Text组件的值以断言生成的文本是否正确。

我创建了一个简单的测试来说明这个问题。我想获取文本值,即"text"。我尝试了几种方法,如果我获取finder asString(),我可以解释字符串以获取值,但是我不认为这是一个好的解决方案。我希望将组件读取为Text,以便我可以访问所有属性。

那么,我要如何读取Text小部件,以便我可以访问数据属性?

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('my first widget test', (WidgetTester tester) async {

    await tester
        .pumpWidget(MaterialApp(home: Text("text", key: Key('unit_text'))));

    // This works and prints: (Text-[<'unit_text'>]("text"))
    var finder = find.byKey(Key("unit_text"));
    print(finder.evaluate().first);

    // This also works and prints: (Text-[<'unit_text'>]("text"))
    var finderByType = find.byType(Text);
    print(finderByType.evaluate().first);

    // This returns empty
    print(finder.first.evaluate().whereType<Text>());

    // This throws: type 'StatelessElement' is not a subtype of type 'Text' in type cast
    print(finder.first.evaluate().cast<Text>().first);

  });
}

你的代码中 find 是从哪里来的? - xetra11
3个回答

60

我解决了这个问题,我需要访问该元素的小部件属性,然后将其转换为文本:

var text = finder.evaluate().single.widget as Text;
print(text.data);

3
您可能需要使用 whereType<Text>() 而不是类型转换。 - Rémi Rousselet
1
whereType<Text>() won't work, since you iterate not over Texts, but StatelessWidgets. You need to access .widget property to get Text - Ilya Ivanov
1
稍微详细解释一下,我最终使用了以下代码:final fieldWidget = find.byType(TextField).evaluate().first.widget; final fieldTextValue = (fieldWidget as TextField).controller?.text; - Maks
我只需要这个答案中的 (.... as Text).data 部分。 - undefined

28
请检查这个简单的例子。
testWidgets('Test name', (WidgetTester tester) async {

// finding the widget
var textFind = find.text("text_of_field");

// checking widget present or not
expect(textFind, findsOneWidget);

// getting Text object
Text text = tester.firstWidget(textFind);

// validating properties
expect(text.style.color, Colors.black);
...
...

}

理解textFind是Finder和tester,以及firstWidget是Widget,帮助我理解这个重要但简单的事实。 - user2244131

5
你可以使用find.texthttps://flutter.cn/docs/cookbook/testing/widget/finders#1-find-a-text-widget
testWidgets('finds a Text Widget', (WidgetTester tester) async {
  // Build an App with a Text Widget that displays the letter 'H'
  await tester.pumpWidget(MaterialApp(
    home: Scaffold(
      body: Text('H'),
    ),
  ));

  // Find a Widget that displays the letter 'H'
  expect(find.text('H'), findsOneWidget);
});

8
我不太喜欢这种方法。以我的例子为考虑:我正在使用flutter制作一个简单的游戏,在我的测试中,我检查屏幕上是否有文本“1”。屏幕上可能会有多个“1”,但并非我所期望的。在这种情况下,测试将会通过。我真正想要的是确保特定元素的文本符合预期。因此,我使用find.byKey(Key('Health')),在生产代码中我编写Text(myHealth, key: Key('Health')) - Ilya Ivanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接