flutter 如何模拟单元测试中Navigator.of(context).push()返回的内容?

bn31dyow  于 2023-03-24  发布在  Flutter
关注(0)|答案(1)|浏览(198)

我正在为一个函数编写单元测试。
函数的结构如下:

final isUpdated = await Navigator.of(context).pushNamed([route]);

if (isUpdated) {
    [update some global variables]
}

只有当用户使用true布尔值弹出Navigator从下一页返回时,全局变量才会更改。
我不想检查/验证是否发生了push或pop,我想模拟Navigator.of(context).pushNamed()调用,在一个测试中返回true,在另一个测试中返回false,这样我就可以验证全局变量是否得到更新。
我尝试编写的测试代码看起来像这样:

TEST 1 {

when: Navigator.pushNamed([route])
then answer: true

call function

expect: global variables to be updated
}

TEST 2 {

when: Navigator.pushNamed([route])
then answer: false

call function

expect: global variables to NOT be updated
}

我已经查了很多,但还没有找到解决办法。任何帮助将不胜感激。

2hh7jdfx

2hh7jdfx1#

我发现的解决方案是在测试中抽取2个按钮小部件,第一个调用我们正在测试的函数,第二个包含Navigator.of(context).pop()调用。第二个应该匹配函数的Navigator.of(context).pushNamed([route])中使用的任何路由。
下面是一个代码片段来澄清:

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

void main() {
  testWidgets('test function', (WidgetTester tester) async {
    // Build the widget that contains the button
    await tester.pumpWidget(MaterialApp(
      onGenerateRoute: (settings) {
        if (settings.name == "[route name used in function's pushNamed()]") {
          return MaterialPageRoute(builder: (context) => SecondPage());
        }
        return null;
      },
      home: Scaffold(
        body: Center(
          child: ElevatedButton(
            child: Text('Go to Second Page'),
            onPressed: () {
              // call function that's being tested here
            },
          ),
        ),
      ),
    ));

    // Tap the button to navigate to the SecondPage
    await tester.tap(find.text('Go to Second Page'));
    await tester.pumpAndSettle();

    // Tap the button to go back to the home page
    await tester.tap(find.text('Go Back'));
    await tester.pumpAndSettle();

    // add expect() here to check if the global variables were updated or not
  });
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Go Back'),
          onPressed: () {
            // Navigator.of(context).pop(true); test 1
            // Navigator.of(context).pop(); test 2
          },
        ),
      ),
    );
  }
}

相关问题