flutter - 如何模拟导航参数以测试 flutter 屏幕小部件?

标签 flutter mocking mockito flutter-test

我想为Flutter中的屏幕小部件编写一个模拟测试。问题是,此小部件使用导航参数中的变量,但我不确定如何模拟此变量。

这是示例屏幕:

class TestScreen extends StatefulWidget {
  static final routeName = Strings.contact;

  @override
  _TestScreenState createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {
  Contact _contact;

  @override
  Widget build(BuildContext context) {
    _contact = ModalRoute.of(context).settings.arguments;

    return Scaffold(
      appBar: AppBar(title: Text(Strings.contact)),
      body: Text(_contact.name),
    );
  }
}

用这个命令我打开屏幕

Navigator.pushNamed(context, TestScreen.routeName, arguments: contact);

通常我会模拟一些组件,但是我不确定如何模拟屏幕参数。我希望它的工作原理是这样的。但是,我不知道我能完全 mock 什么。

when(screenArgument.fetchData(any))
    .thenAnswer((_) async => expectedContact);

这是当前测试,由于_contact为null,因此当然不起作用:

void main() {
  testWidgets('contact fields should be filled with data from argument', (WidgetTester tester) async {
    // GIVEN
    final testScreen = TestApp(widget: TestScreen());

    // WHEN
    await tester.pumpWidget(testScreen);

    // THEN
    expect(find.text("test"), findsOneWidget);
  });
}

一个丑陋的方法是只在屏幕上使用构造函数参数进行测试,但我想避免这种情况。

也许你们当中有人知道如何最好地测试这样的屏幕小部件。

最佳答案

我发现的方法与 flutter 的人如何测试它的方法相同:
https://github.com/flutter/flutter/blob/d03aecab58f5f8b57a8cae4cf2fecba931f60673/packages/flutter/test/widgets/navigator_test.dart#L715

基本上,他们创建了一个MaterialApp,放置了一个按钮,按下后将导航到测试页面。

我修改后的解决方案:


Future<void> pumpArgumentWidget(
  WidgetTester tester, {
  @required Object args,
  @required Widget child,
}) async {
  final key = GlobalKey<NavigatorState>();
  await tester.pumpWidget(
    MaterialApp(
      navigatorKey: key,
      home: FlatButton(
        onPressed: () => key.currentState.push(
          MaterialPageRoute<void>(
            settings: RouteSettings(arguments: args),
            builder: (_) => child,
          ),
        ),
        child: const SizedBox(),
      ),
    ),
  );

  await tester.tap(find.byType(FlatButton));
  await tester.pumpAndSettle(); // Might need to be removed when testing infinite animations
}

这种方法行之有效,测试进度指示器存在一些问题,因为即使debugDumpApp显示了它们也无法找到它们。

关于flutter - 如何模拟导航参数以测试 flutter 屏幕小部件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57005472/

相关文章:

android - Flutter:默认选项卡栏 Controller 在滑动后不保持状态

android - 在 Flutter 中重命名文件或图像

PHPUnit、模拟接口(interface)和 instanceof

java - 模拟返回带有捕获泛型的迭代器的方法

java - 具体类 Mockito 中的模拟链式调用

flutter 语音到文本识别器不可用

flutter - CORS flutter 网

java - 如何在 Mockito 中模拟 instanceof

python - 以可模拟/可测试的方式连接文件

java - 如何计算使用 Junit 和 Mockito 调用某个方法的次数?