Flutter: testing shared preferences
Solution 1
You can use SharedPreferences.setMockInitialValues
for your test
test('Can Create Preferences', () async{
SharedPreferences.setMockInitialValues({}); //set values here
SharedPreferences pref = await SharedPreferences.getInstance();
bool working = false;
String name = 'john';
pref.setBool('working', working);
pref.setString('name', name);
expect(pref.getBool('working'), false);
expect(pref.getString('name'), 'john');
});
Solution 2
Thanks to nonybrighto for the helpful answer.
I ran into trouble trying to set initial values in shared preferences using:
SharedPreferences.setMockInitialValues({
"key": "value"
});
It appears that the shared_preferences plugin expects keys to have the prefix flutter.
. This therefore needs adding to your own keys if mocking using the above method.
See line 20 here for evidence of this: https://github.com/flutter/plugins/blob/2ea4bc8f8b5ae652f02e3db91b4b0adbdd499357/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart
Solution 3
I don't know if that helps you but I also lost a lot of time before finding this solution
LocalDataSourceImp.test.dart
void main(){
SharedPreferences? preference;
LocalDataSourceImp? localStorage ;
setUp(() async{
preference = await SharedPreferences.getInstance();
localStorage = LocalDataSourceImp(preference!);
SharedPreferences.setMockInitialValues({});
});
final token = TokenModel(data: "babakoto");
test("cache Token ", ()async{
localStorage!.cacheToken(token);
final result = preference!.getString(TOKEN);
expect(result, json.encode(token.toJson()));
});
}
LocalDataSourceImp.dart
class LocalDataSourceImp implements LocalDataSource{
SharedPreferences pref ;
LocalDataSourceImp(this.pref);
@override
Future<void> cacheToken(TokenModel token)async {
await pref.setString(TOKEN,json.encode(token));
}
}
Comments
-
Little Monkey over 1 year
I'm trying to test this function:
void store(String x, String y) async { Map<String, dynamic> map = { 'x': x, 'y': y, }; var jsonString = json.encode(map); SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setString('fileName', jsonString); }
I saw that I can populate the shared preferences with
const MethodChannel('plugins.flutter.io/shared_preferences') .setMockMethodCallHandler((MethodCall methodCall) async { if (methodCall.method == 'getAll') { return <String, dynamic>{}; // set initial values here if desired } return null; });
But I didn't understand how to use, expecially in my case.
-
Luke Pighetti over 5 yearsI keep getting errors when trying to test
shared_preferences
. Is it because I am runningflutter test
and not using a device to test? -
nonybrighto over 5 yearsNo. You should be able to use it in flutter test. What kind of error are you getting?
-
Luke Pighetti over 5 yearsI got it handled, I can't remember what the issue was though. Thank you!
-
woprandi almost 5 yearsI have an error : "Used on a non-mockito object" if I use
verify(pref.setString(any, any)).called()
-
nonybrighto almost 5 yearsYeah. It won't work with mockito. mockito expects an object that extends Mock like
class MockSharedPreference extends Mock implements SharedPreferences{}
. I don't really know how to make this work. -
Simon Hutton over 4 yearsThe link above is broken
-
Richard Thomas about 4 yearsThanks @SimonH - updated with link to new file location.
-
Hashem Aboonajmi over 3 yearsits not required. it automatically prefix the key: github.com/flutter/plugins/blob/…
-
Maciej almost 3 years@HashemAboonajmi is right, your answer doesn't apply to the revision you linked (nor to the most recent one)
-
Karolina Hagegård almost 2 yearsWhere does
SharedPreferences.setMockInitialValues({});
come from? I get "Undefined name" for it... -
Tokiniaina Eddy Andriamiandris almost 2 yearstesting code pub.dev/packages/shared_preferences
-
Karolina Hagegård almost 2 yearsOk, thanks. Please include that information in your Answer, so that it's complete and runnable! 🙂