如何在 Flutter 中存根目标平台
Posted
技术标签:
【中文标题】如何在 Flutter 中存根目标平台【英文标题】:How to stub target platform in Flutter 【发布时间】:2019-12-28 21:23:22 【问题描述】:假设我有一个根据平台行为不同的小部件:
如果平台是 android,则会显示RaisedButton
。
如果平台是 ios,则显示CupertinoButton
。
例子:
@override
Widget build(BuildContext context)
if (Platform.isAndroid)
return buildRaisedButton();
else if (Platform.isIOS)
return buildCupertinoButton();
else
throw UnsupportedError('Only Android and iOS are supported.');
在我的widget tests 中,我希望能够测试这两种情况,但是由于Platform
的getter 是静态的,所以我不能对它们进行存根。
关于如何实现这一点的任何想法?
【问题讨论】:
【参考方案1】:tl;博士
使用Theme
确认目标平台:
@override
Widget build(BuildContext context)
final platform = Theme.of(context).platform;
if (platform == TargetPlatform.iOS)
return buildCupertinoButton();
else
...
通过设置debugDefaultTargetPlatformOverride
来存根目标平台:
testWidgets('`CupertinoButton` is shown in iOS.', (tester) async
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
// run your tests
debugDefaultTargetPlatformOverride = null;
);
确认目标平台
为了使您的代码更易于测试,目标平台应从Theme
确认,而不是从Platform
:
@override
Widget build(BuildContext context)
final platform = Theme.of(context).platform;
if (platform == TargetPlatform.android)
return buildRaisedButton();
else if (platform == TargetPlatform.iOS)
return buildCupertinoButton();
else
throw UnsupportedError('Only Android and iOS are supported.');
getter defaultTargetPlatform
应该能够覆盖您无法访问 BuildContext
的情况。
存根目标平台
要存根目标平台,您必须设置debugDefaultTargetPlatformOverride
。默认情况下,Android 是小部件测试的目标平台。
例子:
testWidgets('`CupertinoButton` is shown in iOS.', (tester) async
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
await tester.pumpWidget(MyWidget());
expect(find.byType(RaisedButton), findsNothing);
expect(find.byType(CupertinoButton), findsOneWidget);
debugDefaultTargetPlatformOverride = null;
);
注意最后一行:debugDefaultTargetPlatformOverride = null
。
这是必要的,因为在函数testWidgets()
内部发生的绑定过程中,BindingBase.initServiceExtensions()
方法根据操作系统确定debugDefaultTargetPlatformOverride
的值。如果操作系统不是移动的(Android、iOS 或 Fuchsia),null
会被归属。
在测试结束时,testWidgets()
调用函数debugAssertAllFoundationVarsUnset()
检查debugDefaultTargetPlatformOverride
是否为null
,以确保您没有忘记将其重置为默认值。必须这样做,因为debugDefaultTargetPlatformOverride
是一个在测试中持续存在的***变量。
重要提示:您可能很想将debugDefaultTargetPlatformOverride = null
移动到tearDown()
,但由于debugAssertAllFoundationVarsUnset()
在tearDown()
之前被调用,它不会起作用。
【讨论】:
以上是关于如何在 Flutter 中存根目标平台的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 集成测试中最好地存根/模拟 rest API 调用