Flutter: testing shared preferences

8,463

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));
  }

}
Share:
8,463
Little Monkey
Author by

Little Monkey

I'm just a little monkey!

Updated on December 07, 2022

Comments

  • Little Monkey
    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
    Luke Pighetti over 5 years
    I keep getting errors when trying to test shared_preferences. Is it because I am running flutter test and not using a device to test?
  • nonybrighto
    nonybrighto over 5 years
    No. You should be able to use it in flutter test. What kind of error are you getting?
  • Luke Pighetti
    Luke Pighetti over 5 years
    I got it handled, I can't remember what the issue was though. Thank you!
  • woprandi
    woprandi almost 5 years
    I have an error : "Used on a non-mockito object" if I use verify(pref.setString(any, any)).called()
  • nonybrighto
    nonybrighto almost 5 years
    Yeah. 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
    Simon Hutton over 4 years
    The link above is broken
  • Richard Thomas
    Richard Thomas about 4 years
    Thanks @SimonH - updated with link to new file location.
  • Hashem Aboonajmi
    Hashem Aboonajmi over 3 years
    its not required. it automatically prefix the key: github.com/flutter/plugins/blob/…
  • Maciej
    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
    Karolina Hagegård almost 2 years
    Where does SharedPreferences.setMockInitialValues({}); come from? I get "Undefined name" for it...
  • Tokiniaina Eddy Andriamiandris
    Tokiniaina Eddy Andriamiandris almost 2 years
  • Karolina Hagegård
    Karolina Hagegård almost 2 years
    Ok, thanks. Please include that information in your Answer, so that it's complete and runnable! 🙂