#flutter
#flutter
Вопрос:
В коде моего виджета мне нужно выполнить ветвление на Android / iOS, чтобы показывать виджеты, специфичные для каждой платформы, а также вызывать API, специфичные для платформы (например, виджет Android вызовет API, доступный только на Android).
if (Platform.isAndroid) {
return WidgetAndroid(...);
} else if (Platform.isIOS) {
return WidgetIOS(...);
}
Как я могу проверить, отображается ли правильный виджет, используя тест виджета Flutter?
Я знаю, что могу проверить, существует ли виджет, но как мне запустить тест с определенной платформой.
expect(find.byType(WidgetIOS), findsOneWidget);
Комментарии:
Ответ №1:
В 2022 году не рекомендуется использовать dart:io
и Platform
class для определения платформы выполнения. Лучшей альтернативой является использование, defaultTargetPlatform
доступное через ‘package: flutter /foundation.dart’. Т.е.:
if (defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS) {}
Если у вас есть такой подход к определению платформы в вашем коде, переопределить платформу в тестах так же просто, как настроить debugDefaultTargetPlatformOverride
в теле вашего теста.
https://api.flutter.dev/flutter/foundation/debugDefaultTargetPlatformOverride.html
Например.:
testWidgets('DataTable2 renders with DataRow.index()',
(WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
...
debugDefaultTargetPlatformOverride = null;
});
Ответ №2:
Оба Platform.isAndroid
и Platform.isIOS
возвращаются false
при запуске testWidgets
.
Некоторые предложения, которые мы можем применить в наших тестах:
- Передайте платформу в качестве переменной вашему виджету верхнего уровня, таким образом, вы сможете ввести это значение вручную.
- Укажите случай, когда вы хотите протестировать
else
безif
, чтобы это выполнялось во время тестов. - Используйте вместо этого
Platform
из https://pub.dev/packages/platform что позволяет издеваться, что, вероятно, является лучшим долгосрочным решением.
Ответ №3:
Platform
находится в dart:io
, который находится на более низком уровне, чем у Flutter TargetPlatform
. В большинстве случаев вам следует использовать последнее.
Из документации:
Объект [dart:io.Platform] следует использовать напрямую только тогда, когда действительно важно знать текущую платформу, без каких-либо возможных переопределений (например, когда готовится вызов системного API).
Ответ №4:
Как упоминал Мигель, вы не можете издеваться над ним напрямую.
Если вы используете платформу provider, вы можете использовать внедрение зависимостей в свои тесты, чтобы это произошло, не предоставляя дополнительных параметров в вашем виджете.
Создайте класс, который будет использоваться для внедрения:
class PlatformInfo {
final bool isIos;
final bool isAndroid;
PlatformInfo({@required this.isAndroid,@required this.isIos});
}
в вашем виджете верхнего уровня MultiProvider
настройте привязки вашего поставщика:
Provider<PlatformInfo>.value(
value: PlatformInfo(isAndroid: Platform.isAndroid, isIos: Platform.isIOS),
),
Используйте это в своем виджете:
Provider.of<PlatformInfo>(context).isIos