我尝试对自己的小部件进行单元测试:
testWidgets('MyWidget has a title and message', (WidgetTester tester) async {
var text = "abc";
var label = "def";
await tester.pumpWidget(LabeledTextWidget(
text,
label: label,
));
final textFinder = find.text(text);
final labelFinder = find.text(label);
expect(textFinder , findsOneWidget);
expect(labelFinder, findsOneWidget);
});
这是小部件代码:
class LabeledTextWidget extends StatelessWidget {
final String text;
final String label;
LabeledTextWidget(this.text, {this.label});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(label,style: Theme.of(context).textTheme.caption,),
Text(text),
],
);
}
测试始终会引发异常:
...
No Directionality widget found.
RichText widgets require a Directionality widget ancestor.
The specific widget that could not find a Directionality ancestor was:
RichText
...
我可以通过向所有文本小部件添加文本方向来避免此错误。 (textDirection:TextDirection.ltr,),但是那是一个不好的解决方案,它不适用于行。
答案 0 :(得分:1)
好的,这是解决方法。
您必须使用以下方法包装小部件:
Directionality(
child: MediaQuery(
data: MediaQueryData(),
child: LabeledTextWidget(this.text, {this.label}),
),
textDirection: TextDirection.ltr,
);
答案 1 :(得分:0)
在现实世界中的Flutter应用中,先要准备好要测试的Widget可能取决于一堆框架Widget,而您可能会遇到许多错误:
没有找到方向性小部件,没有找到MaterialLocalizations,没有材料小部件,没有覆盖等。
最好的方法是提取main.dart
入口点并提取最低限度的内容(通过反复试验)。这是我的pumpWidget
示例,是我创建并包装目标OnlineDictionaries
小部件的情况:
await tester.pumpWidget(
MultiProvider(
providers: [
ChangeNotifierProvider<OnlineDictionaryManager>(
create: (context) => OnlineDictionaryManager(FakeOnlineRepo()),
)
],
child: MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''),
const Locale('be', ''),
const Locale('ru', ''),
],
initialRoute: '/',
routes: {'/': (context) => Scaffold(body: OnlineDictionaries())},
),
),
);
请注意,OnlineDictionaries
小部件依赖于状态管理的提供程序,它使用本地化,并且应用程序使用Overlays / Navigator(由initialRoute
和routes
属性寻址)。
此后,您可以操作该小部件(例如,检查是否显示了加载指示器,并且如果清除了TextFormField,是否显示了错误消息):
await tester
.pump(Duration(milliseconds: 10)); // let progress indicator appear
expect(find.byType(LinearProgressIndicator), findsOneWidget);
await tester.pumpAndSettle();
var field = find.byType(TextFormField);
expect(field, findsOneWidget);
await tester.enterText(find.byType(TextFormField), '');
await tester.pumpAndSettle(Duration(milliseconds: 100));
final errorFinder = find.text('URL can\'t be empty');
expect(errorFinder, findsOneWidget);
这是一个完整的示例(还包括Mockito和嘲笑的SharedPreferences):https://github.com/maxim-saplin/dikt/blob/master/test/ui_dictionaries_test.dart