我想为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/