Flutter - how to test localized widgets?
Asked Answered
H

1

5

I read the answer to this question, but it didn't help me to understand what to do in my case, maybe also because the question is a bit old. So, I am asking this again.

I created a new flutter project with the skeleton template:

flutter create skeleton -t skeleton

I change the file sample_item_details_view.dart as following:

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

Now, I want to write a widget test for this widget:

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());
    });
  });
}

This is failing with the following error because AppLocalizations.of(context) is NULL

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

What are the steps that I need to do, in order to test SampleItemDetailsView?

Hourihan answered 6/11, 2021 at 9:31 Comment(0)
M
11

This is because AppLocalizations was injected in the context by MaterialApp widget, inside app.dart. There is no AppLocalizations in your test's context. One possible solution is creating a widget helper to inject this kind of dependency, like this:

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,
    );
  }
}

You might want to parameterize the values to customize your test cases. And then, you use like this:

void main() {
  group('Sample item details', () {
    testWidgets('should display appbar', (WidgetTester tester) async {
      await tester.pumpWidget(const LocalizationsInj(child: SampleItemDetailsView()));
    });
  });
}
Montes answered 6/11, 2021 at 13:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.