I have a utility class that relies on the context in order to translate the output. Something along the lines of :
static String doSomeLogicAndTranslate(String firstArg, BuildContext context) {
//...
return AppLocalizations.of(context)!.someKey;
}
Now, I want to be able to write some unit tests for this class, but since the second argument is the context, I'm having a hard time doing so.
What I have tried so far:
Mocking a BuildContext with Mockito (as described here) and passing that as the second argument --> Doesn't work as inside the localizations.dart file it returns null here
static T? of<T>(BuildContext context, Type type) {
final _LocalizationsScope? scope = context.dependOnInheritedWidgetOfExactType<_LocalizationsScope>(); /// Scope is null here
return scope?.localizationsState.resourcesFor<T?>(type);
}
I have tried looking around for any other solutions for this, but have not found anything substantial. This seems like it should be pretty straight forward, but it isn't.
My first suggestion would be to remove the dependency on BuildContext
altogether by passing AppLocalizations
directly to your function:
static String doSomeLogicAndTranslate(String firstArg, AppLocalizations loc) {
//...
return loc.someKey;
}
test('AppLocalizations test', () {
final loc = lookupAppLocalizations(const Locale('en'));
final output = doSomeLogicAndTranslate('some arg', loc);
// Calls to expect or whatever here
});
If that's not possible for some reason, you can use testWidgets
to set up a minimal widget tree and retrieve a valid build context for the rest of your test from there:
testWidgets('AppLocalizations test', (tester) async {
await tester.pumpWidget(
Localizations(
locale: const Locale('en'), // Or whichever locale you prefer to test with
delegates: AppLocalizations.localizationsDelegates,
child: Container(),
),
);
final BuildContext context = tester.element(find.byType(Container));
final output = doSomeLogicAndTranslate('some arg', context);
// Calls to expect or whatever here
});