如何在 Flutter 中存根目标平台
How to stub target platform in Flutter
假设我有一个根据平台表现不同的小部件:
- 如果平台是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 是静态的,我无法对它们进行存根。
关于如何实现此目标的任何想法?
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()
根据 OS 确定 [=15= 的值].如果操作系统不是移动操作系统(Android、iOS 或 Fuchsia),null
会被归因。
在测试结束时,testWidgets()
调用函数 debugAssertAllFoundationVarsUnset()
检查 debugDefaultTargetPlatformOverride
是否为 null
以确保您没有忘记重置它到默认值。必须这样做,因为 debugDefaultTargetPlatformOverride
是一个在测试中持续存在的顶级变量。
重要提示:您可能想将 debugDefaultTargetPlatformOverride = null
移动到 tearDown()
,但它不会起作用,因为之前调用了 debugAssertAllFoundationVarsUnset()
tearDown()
.
假设我有一个根据平台表现不同的小部件:
- 如果平台是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 是静态的,我无法对它们进行存根。
关于如何实现此目标的任何想法?
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()
根据 OS 确定 [=15= 的值].如果操作系统不是移动操作系统(Android、iOS 或 Fuchsia),null
会被归因。
在测试结束时,testWidgets()
调用函数 debugAssertAllFoundationVarsUnset()
检查 debugDefaultTargetPlatformOverride
是否为 null
以确保您没有忘记重置它到默认值。必须这样做,因为 debugDefaultTargetPlatformOverride
是一个在测试中持续存在的顶级变量。
重要提示:您可能想将 debugDefaultTargetPlatformOverride = null
移动到 tearDown()
,但它不会起作用,因为之前调用了 debugAssertAllFoundationVarsUnset()
tearDown()
.