模拟默认的 SharedPreferences

Mocking default SharedPreferences

提问人:Jonathan Chiou 提问时间:11/17/2018 更新时间:11/20/2018 访问量:715

问:

所以我有一个类,它通过构造函数接受一个,并使用以下命令从中获取默认值:ContextSharedPreferences

PreferenceManager.getDefaultSharedPreferences(context)

我正在测试这个类,在我的单元测试中,我编写了以下代码来检索调用时的模拟实例:SharedPreferencesgetSharedPreferences(String, int)

Context context = mock(Context.class);
SharedPreferences sharedPreferences = mock(SharedPreferences.class);

when(context.getSharedPreferences(anyString(), anyInt()))
            .thenReturn(sharedPreferences);
when(sharedPreferences.getString(anyString(), nullable(String.class)))
            .thenReturn(tokenManager.getToken());

当我为这个类运行测试时,它最终会得到一个对象,而不是我模拟的 SharedPreferences 实例。但是,如果我用 抓取实例,我最终会得到我的模拟代码。nullSharedPreferencescontext.getSharedPreferences("stubbed", 123)SharedPreferences

那么,为什么在直接调用我的模拟实例时返回实例会返回我的模拟实例呢?PreferenceManager.getDefaultSharedPreferences(context)nullgetSharedPreferencesContextSharedPreferences

Java Android mockito 共享首选项

评论

0赞 P.J.Meisch 11/18/2018
你检查过代码吗?PM 如何从 ?PreferenceManager.getDefaultSharedPreferences(context)context
0赞 Jonathan Chiou 11/20/2018
'return context.getSharedPreferences(getDefaultSharedPreferencesName(context), getDefaultSharedPreferencesMode());''

答:

0赞 Jonathan Chiou 11/20/2018 #1

基于本文档(https://developer.android.com/training/testing/unit-testing/local-unit-tests)并逐行调试代码,我得出的关于为什么会发生这种情况的结论是因为 gradle 中用于单元测试的 android 代码实际上只是一个 shell,它在每个方法调用时都返回存根值,所以很自然地,这让我假设我的单元测试中使用的代码或多或少。PreferenceManager.getDefaultSharedPreferences()return null

0赞 P.J.Meisch 11/20/2018 #2

因此,您需要模拟对 的静态调用。目前,这是不可能的,因为相应的问题仍在讨论中。PreferenceManager.getDefaultSharedPreferences(context)

这个问题的公认答案中显示了一种解决方案,您可以检查 PowerMockJMockit 作为替代方案