首页 > 解决方案 > Flutter - 如何测试本地化的小部件?

问题描述

我阅读了这个问题的答案,但它并没有帮助我理解在我的情况下该怎么做,也许也是因为这个问题有点老了。所以,我再次问这个问题。

我用骨架模板创建了一个新的颤振项目:

flutter create skeleton -t skeleton

我将文件更改sample_item_details_view.dart如下:

 Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context)!.itemDetails),
      ),
      body: Center(
        child: Text(AppLocalizations.of(context)!.itemDetailsMoreInfo),
      ),
    );
  }

现在,我想为这个小部件编写一个小部件测试:

import 'package:skeleton/src/sample_feature/sample_item_details_view.dart';

void main() {
  group('Sample item details', () {
    testWidgets('should display appbar', (WidgetTester tester) async {
      await tester.pumpWidget(const SampleItemDetailsView());
    });
  });
}

这失败并出现以下错误,因为AppLocalizations.of(context)是 NULL

The following _CastError was thrown building SampleItemDetailsView(dirty):
Null check operator used on a null value

为了测试,我需要执行哪些步骤SampleItemDetailsView

标签: flutterlocalizationautomated-tests

解决方案


这是因为 AppLocalizations 是由 MaterialApp 小部件在上下文中注入的,在app.dart. 您的测试上下文中没有 AppLocalizations。一种可能的解决方案是创建一个小部件助手来注入这种依赖项,如下所示:

class LocalizationsInj extends StatelessWidget {
  final Widget child;
  const LocalizationsInj({Key? key, required this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('en', ''),
      ],
      home: child,
    );
  }
}

您可能希望参数化这些值以自定义您的测试用例。然后,你像这样使用:

void main() {
  group('Sample item details', () {
    testWidgets('should display appbar', (WidgetTester tester) async {
      await tester.pumpWidget(const LocalizationsInj(child: SampleItemDetailsView()));
    });
  });
}

推荐阅读