[英]Flutter widget tests with platform branching
In my widget's code I need to branch on Android/iOS to show widgets specific to each platform, and also call platform specific APIs (eg the Android widget will call an API only available on Android).在我的小部件代码中,我需要在 Android/iOS 上进行分支以显示特定于每个平台的小部件,并调用特定于平台的 API(例如,Android 小部件将调用仅在 Android 上可用的 API)。
if (Platform.isAndroid) {
return WidgetAndroid(...);
} else if (Platform.isIOS) {
return WidgetIOS(...);
}
How can I test that the right widget is shown using a Flutter widget test?如何使用 Flutter 小部件测试来测试是否显示了正确的小部件?
I know I can check that the widget exists but how do I run the test with a specific platform.我知道我可以检查小部件是否存在,但是如何使用特定平台运行测试。
expect(find.byType(WidgetIOS), findsOneWidget);
Both Platform.isAndroid
and Platform.isIOS
return false
when running testWidgets
.运行testWidgets
时Platform.isAndroid
和Platform.isIOS
都返回false
。
Some suggestions we can apply in our tests:我们可以在测试中应用一些建议:
else
without if
, so that will run during the tests.使您想在没有if
的情况下测试else
的情况,以便在测试期间运行。Platform
from https://pub.dev/packages/platform which allows mocking, which is probably the best long term solution.改用来自https://pub.dev/packages/platform的Platform
,它允许模拟,这可能是最好的长期解决方案。Like Miguel mentioned you can't mock it directly.就像 Miguel 提到的那样,您不能直接模拟它。
If you use the provider framework, you can use dependency injection in your tests to make this happen without exposing an additional param in your widget.如果您使用提供者框架,您可以在测试中使用依赖注入来实现这一点,而无需在小部件中暴露额外的参数。
Create an class to use for injection:创建一个用于注入的类:
class PlatformInfo {
final bool isIos;
final bool isAndroid;
PlatformInfo({@required this.isAndroid,@required this.isIos});
}
in your top level MultiProvider
widget, set up your provider bindings:在您的顶级MultiProvider
小部件中,设置您的提供程序绑定:
Provider<PlatformInfo>.value(
value: PlatformInfo(isAndroid: Platform.isAndroid, isIos: Platform.isIOS),
),
Use it in your widget:在您的小部件中使用它:
Provider.of<PlatformInfo>(context).isIos
Platform
is in dart:io
, which is lower-level than Flutter's TargetPlatform
. Platform
位于dart:io
中,比 Flutter 的TargetPlatform
低级。 In most cases, you should use the latter.在大多数情况下,您应该使用后者。
From documentation :从文档:
The [dart:io.Platform] object should only be used directly when it's critical to actually know the current platform, without any overrides possible (for example, when a system API is about to be called). [dart:io.Platform] 对象应该只在实际了解当前平台至关重要时直接使用,而不能进行任何覆盖(例如,当即将调用系统 API 时)。
In 2022 it is not recommended to use dart:io
and Platform
class to determine the runtime platform.在 2022 年不建议使用dart:io
和Platform
类来确定运行时平台。 The better alternative is to use defaultTargetPlatform
available through 'package:flutter/foundation.dart'.更好的选择是使用通过 'package:flutter/foundation.dart' 提供的defaultTargetPlatform
。 Ie: IE:
if (defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS) {}
Should you have that approach for determining platform in your code overiding platform in tests is as easy as setting debugDefaultTargetPlatformOverride
in your test body.如果您有这种方法来确定测试中代码覆盖平台的平台,就像在测试主体中设置debugDefaultTargetPlatformOverride
一样简单。
https://api.flutter.dev/flutter/foundation/debugDefaultTargetPlatformOverride.html https://api.flutter.dev/flutter/foundation/debugDefaultTargetPlatformOverride.html
Eg:例如:
testWidgets('DataTable2 renders with DataRow.index()',
(WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
...
debugDefaultTargetPlatformOverride = null;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.