Reputation: 575
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.
Upvotes: 25
Views: 15818
Reputation: 921
For just accessing localised text in a widget test, the translation for a specific locale can be accessed in a static way. By Fixing the widget under test to a known language, the actual text for that language can be used to e.g. find a Text
widget:
import 'package:flutter_gen/gen_l10n/app_localizations_en.dart';
// etc...
void main() {
// Concrete instance of English translations
final localized = AppLocalizationsEn();
testWidgets('finds localized text', (tester) async {
await tester.pumpMyView();
expect(find.text(localized.myLocalizedText), findsOneWidget);
});
}
/// Adds the view under test to [WidgetTester]
extension on WidgetTester {
Future<void> pumpMyView() async {
await pumpWidget(
MaterialApp(
localizationsDelegates: const [
GlobalCupertinoLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
AppLocalizations.delegate,
],
supportedLocales: AppLocalizations.supportedLocales,
locale: const Locale('en'), // Fixed to ENGLISH
home: Scaffold(
body: Builder(
builder: (context) {
return Text(AppLocalizations.of(context).myLocalizedText);
},
),
),
),
);
}
}
Note that you can extract the common application setup part to a common extension on WidgetTester
that can be used across many widget tests.
Upvotes: 0
Reputation: 971
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;
}
Upvotes: 0
Reputation: 228
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 :)
Upvotes: 4
Reputation: 4580
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
Upvotes: 3
Reputation: 1730
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
Upvotes: 2
Reputation: 21
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.
Upvotes: 5
Reputation: 276947
You can wrap the widget you want to tests into a Localizations
Localizations(
delegates: [
yourDelegate
],
locale: Locale('en'),
child: YourWidget(),
);
Upvotes: 36