jamesmontemagno / Xamarin.Plugins

Cross-platform Native API Access from Shared Code!
MIT License
1.3k stars 380 forks source link

Testing the ViewModels, how can I mock the SettingsRepository? #289

Closed fcogutierrez closed 8 years ago

fcogutierrez commented 8 years ago

Which plugin does this impact:

Question:

How can I mock my static AppSettings class in my Unit tests?

I am doing this:

public static class AppSettings
{
    private const string EmailKey = "email_key";

    public static string Email
    {
        get { return SettingsRepository.GetValueOrDefault<string>(EmailKey, string.Empty); }
        set { SettingsRepository.AddOrUpdateValue<string>(EmailKey, value); }
    }

    private static ISettings SettingsRepository
    {
        get { return CrossSettings.Current; }
    }
}

Thanks a lot.

jamesmontemagno commented 8 years ago

You would just need to implement a different version of ISettings and then return it when you want to use that mock.

fcogutierrez commented 8 years ago

@jamesmontemagno, thanks but...how can I set my ISettings implementation instead of using CrossSettings.Current?

    private static ISettings SettingsRepository
    {
        get { return CrossSettings.Current; }
    }
jamesmontemagno commented 8 years ago

Simply implement it in a new class and then return it?

fcogutierrez commented 8 years ago

Yes, but how can I replace the CrossSettings.Current by my implementation?

jamesmontemagno commented 8 years ago
private static ISettings SettingsRepository
    {
        get { return new YourImplementation(); }
    }
fcogutierrez commented 8 years ago

Ok @jamesmontemagno , so I have my AppSettings class and my AppSettingsMock class:

However, in my ViewModel (subject under test) I am doing:

        //some operations...
        Email = AppSettings.Email;
        Password = AppSettings.Password;
        //more operations...

And my question is...how can I use my AppSettingsMock instead of the AppSettings class in my test?

Thank you a lot for your help mr James :-) :+1: :+1:

yairsz commented 8 years ago

@fcogutierrez I believe you need to setup a form of iOC. For example in MVVMCross you could do this:

public static string Email
{
    get { 
         var settingsSvc = Mvx.Resolve<ISettingsService>();
         return settingsSvc.GetValueOrDefault<string>(EmailKey, string.Empty); 
}
    set { 
         var settingsSvc = Mvx.Resolve<ISettingsService>();
         settingsSvc .AddOrUpdateValue<string>(EmailKey, value); 
}
}