How to test localized widgets in flutter?
Asked Answered
I

6

24

I added l10n to my flutter app as suggested in the flutter docs, it is suggested to get the localizations with a static method like this:

static DemoLocalizations of(BuildContext context) {
  return Localizations.of<DemoLocalizations>(context, DemoLocalizations);
}

This works fine when running the app, but when I try to test my widgets, the returned value is always null.

Is there any easy way to provide the localizations within the tests?

For now I'm passing through the localizations via DI, but it is quite an overhead.

Interpret answered 23/9, 2018 at 6:48 Comment(0)
W
34

You can wrap the widget you want to tests into a Localizations

Localizations(
  delegates: [
    yourDelegate
  ],
  locale: Locale('en'),
  child: YourWidget(),
);
Wilie answered 23/9, 2018 at 6:54 Comment(2)
This works for me. It was important to wait for the delegate's Future to complete. I used await tester.pumpAndSettle(); to achieve this.Interpret
If you are using "gen_l10n app_localizations" have a look here for an easy to use utility function: https://mcmap.net/q/546725/-how-to-test-localized-widgets-in-flutterInterference
M
5

The above answer didn't help because I was calling strings from json file. The medium blog actually handled my problem in solving the issue.

Menstruate answered 24/2, 2019 at 21:22 Comment(0)
I
3

If you want test existing widgets with in a specific language, you can get the localization by:

import 'package:flutter_localizations/flutter_localizations.dart';
...
(await GlobalMaterialLocalizations.delegate.load(Locale('en'))).okButtonLabel

or

import 'package:flutter_gen/gen_l10n/app_localizations.dart';
...
(await GlobalMaterialLocalizations.delegate.load(Locale('en'))).myCustomLabel
Ives answered 9/6, 2022 at 16:31 Comment(1)
You literally save me, thanks a lot!Botha
I
3

I wrote an universal utility function to make the usage of localization easier inside widget testing:

// Don't forget the import
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

...

Future<AppLocalizations> getLocalizations(WidgetTester t) async {
  late AppLocalizations result;
  await t.pumpWidget(
    MaterialApp(
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      home: Material(
        child: Builder(
          builder: (BuildContext context) {
            result = AppLocalizations.of(context)!;
            return Container();
          },
        ),
      ),
    ),
  );
  return result;
}

In order to grab a localized text in one line you just have to call

 await getLocalizations(t).then((l) => l.YOUR_KEY_HERE)

then. Maybe it's also useful for someone :)

Interference answered 5/8, 2022 at 10:26 Comment(1)
It's not working for me :( The following LateError was thrown running a test: LateInitializationError: Local result has not been initializedEqui
A
2

I think you should read this issues. In case file json over 10kb, it cannot load assets. We should keep following and wait Flutter team fix it or real solution https://github.com/flutter/flutter/issues/22193

Annikaanniken answered 3/6, 2020 at 10:6 Comment(1)
A other way I used linux command to split whole file into some smaller fille and it works.Annikaanniken
E
0

It's modifiable of How to test localized widgets in flutter?

U need to add after return await t.pumpAndSettle();

Full code:

  Future<AppLocalizations> getLocalizationsUnderTests(
    WidgetTester t,
  ) async {
    late AppLocalizations result;
    await t.pumpWidget(
      MaterialApp(
        localizationsDelegates: const <LocalizationsDelegate>[
          GlobalCupertinoLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          AppLocalizations.delegate,
        ],
        supportedLocales: AppLocalizations.supportedLocales,
        locale: const Locale('en'),
        home: Material(
          child: Builder(
            builder: (BuildContext context) {
              result = AppLocalizations.of(context);
              debugPrint('[DEBUG]: locale: $result');

              // The builder function must return a widget.
              return const Placeholder();
            },
          ),
        ),
      ),
    );
    await t.pumpAndSettle();
    return result;
  }
Equi answered 10/10, 2023 at 12:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.