Tom3652
Tom3652

Reputation: 2957

Localization delegate is messing with widget test flutter

I have a custom LocalizationDelegate that deals with my app localizations :

class LocalizationDelegate extends LocalizationsDelegate<Localization> {
  const LocalizationDelegate();

  @override
  bool isSupported(Locale locale) => ['en', 'fr'].contains(locale.languageCode);

  @override
  Future<Localization> load(Locale locale) async {
    String string = await rootBundle
        .loadString("assets/strings/${locale.languageCode}.json");
    language = json.decode(string);
    return SynchronousFuture<Localization>(Localization());
  }

  @override
  bool shouldReload(LocalizationDelegate old) => false;
}

And when i run this test :

testWidgets('Localization test', (WidgetTester tester) async {
    await tester.pumpWidget(const FakeTestPage());
    expect(find.text('TEST'), findsOneWidget);
    print("Done !");
  });

With FakeTestPage :

class FakeTestPage extends StatelessWidget {
  const FakeTestPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      localizationsDelegates: [
        LocalizationDelegate(),
        GlobalCupertinoLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [Locale("fr"), Locale("en")],
      locale: Locale("fr"),
      home: Scaffold(
        body: Text("TEST"),
      ),
    );
  }
}

It throws the error :

/Users/foxtom/Desktop/flutter/bin/flutter --no-color test --machine --start-paused test/localization_test.dart
Testing started at 11:07 ...

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
  Actual: _TextFinder:<zero widgets with text "TEST" (ignoring offstage widgets)>
   Which: means none were found but one was expected

When the exception was thrown, this was the stack:
#4      main.<anonymous closure> (file:///Users/foxtom/StudioProjects/TestProject/test/localization_test.dart:12:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

This was caught by the test expectation on the following line:
  file:///Users/foxtom/StudioProjects/TestProject/test/localization_test.dart line 12
The test description was:
  Localization test
════════════════════════════════════════════════════════════════════════════════════════════════════

Test failed. See exception logs above.
The test description was: Localization test

And if i remove LocalizationDelegate() from the localizationsDelegates parameter in MaterialApp it's working fine.

Is there something wrong with the Future aspect of the delegate ? How can i make this working as it is in my real app ?

Upvotes: 0

Views: 464

Answers (3)

Martin Seibert
Martin Seibert

Reputation: 36

I also had a possibly comparable problem, where suddenly some of my widget tests stopped working. Namely those where I used localized texts. Long story short, I used a symlink to my translation files, because they are outside my flutter project. For unknown reasons the symlink stopped working, but only for widget tests! For integration tests or windows itself the same link works.

To fix this, I put copies of my de/en files into my local assets folder, and then the widget tests succeeded ('assets/i18n/core' is the symlink which stopped working for my widget tests (only!))

Here's the code (see comment) I needed to adapt accordingly:

final localizationDelegates = <LocalizationsDelegate>[
  FlutterI18nDelegate(
    translationLoader: FileTranslationLoader(
      basePath: 'assets',
      // The symlink doesn't work anymore for widget tests
      // basePath: 'assets/i18n/core',
      decodeStrategies: [JsonDecodeStrategy()],
    ),
  ),
  GlobalMaterialLocalizations.delegate,
  GlobalWidgetsLocalizations.delegate,
  GlobalCupertinoLocalizations.delegate,
];

Upvotes: 0

nicover
nicover

Reputation: 2633

You can try the following :

await tester.pumpAndSettle();

From this github issue.

Upvotes: 2

julianniedermaier
julianniedermaier

Reputation: 13

Have a look at this flutter issue: https://github.com/flutter/flutter/issues/134999

You are most likely loading a json file that is too large and your material app therefore doesn't change to the new locale.

Upvotes: -1

Related Questions