【问题标题】:Trying to mock SharedPreferences using Mockito尝试使用 Mockito 模拟 SharedPreferences
【发布时间】:2017-08-25 10:21:12
【问题描述】:

我正在尝试使用 Mockito 测试一个通过SharedPreferences 保存数据的设置管理器。

由于SharedPreferences 使用Context,我需要使用模拟类。

这是我的设置管理器类:

public class SettingsManager implements ISettingsManager {

    protected SharedPreferences prefs;

    public SettingsManager(SharedPreferences prefs) {
        this.prefs = prefs;
    }

    private boolean getBooleanPreference(String key) {
        return prefs.getBoolean(key, true);
    }

    private void setBooleanPreference(boolean enabled, String key) {
        SharedPreferences.Editor editor = prefs.edit();
        editor.putBoolean(key, enabled);
        editor.commit();
    }
}

这是我写的测试用例:

Context mContext = Mockito.mock(Context.class);
SharedPreferences mSharedPreference = Mockito.mock(SharedPreferences.class);
SharedPreferences.Editor mEditor = Mockito.mock(SharedPreferences.Editor.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(mSharedPreference.edit()).thenReturn(mEditor);
Mockito.when(mEditor.commit()).thenReturn(true);
Mockito.when(mEditor.putBoolean(Mockito.anyString(), Mockito.anyBoolean())).thenReturn(mEditor);

SettingsManager manager = new SettingsManager(mSharedPreference);
boolean current = manager.areNotificationsEnabled();
manager.setNotificationsEnabled(!current);
boolean newValue = manager.areNotificationsEnabled();
Assert.assertTrue(newValue != current);

问题是当我设置setNotificationsEnabled 标志时,newValuecurrent 保持不变:SharedPreferences 不保留数据。测试时如何将数据保存到SharedPreferences

【问题讨论】:

    标签: android unit-testing mockito sharedpreferences


    【解决方案1】:

    Robolectric 是这种集成测试的一个选项。

    Robolectric 为常见的 Android 类(如 ContextSQLiteDatabaseSharedPreferences)提供称为“影子”的测试替身。您编写的测试在您的 IDE 中以 test 运行(而不是在模拟器或测试设备上运行 androidTest),因此更容易配置测试覆盖率工具。

    影子SharedPreference 也被沙盒化,因此它不会干扰设备上的实际SharedPreferences

    【讨论】:

    • 我试试看!谢谢你:)
    • robolectrichas 非常糟糕的文档。你能帮我看看使用 robolectric 的任何文档吗?
    【解决方案2】:

    将此转换为 AndroidTest 并使用 InstrumentationRegistry.getTargetContext() 获取上下文,这样您就可以使用该类而无需模拟它

    【讨论】:

    • 但是以这种方式我无法承受代码覆盖率:当我通过选择“使用代码覆盖率运行”运行测试时,我收到此错误:“运行 SettingsInstrumented 时出错...:找不到运行器设置仪表...”。 build.gradle文件中android.defaultConfig.testInstrumentationRunner的值为“android.support.test.runner.AndroidJUnitRunner”
    • @NicolaGiancecchi 检查此blog.wittchen.biz.pl/… 希望对您有所帮助
    猜你喜欢
    • 2016-05-08
    • 2013-01-14
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    相关资源
    最近更新 更多