【问题标题】:Mocking default SharedPreferences模拟默认 SharedPreferences
【发布时间】:2018-11-16 23:14:19
【问题描述】:

所以我有一个通过构造函数接收Context 的类,并使用以下方法从中获取默认的SharedPreferences

PreferenceManager.getDefaultSharedPreferences(context)

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

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

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

那么为什么PreferenceManager.getDefaultSharedPreferences(context) 会返回null 实例,而在我的模拟Context 上直接调用getSharedPreferences 会返回我模拟的SharedPreferences 实例?

【问题讨论】:

  • 你查看PreferenceManager.getDefaultSharedPreferences(context)的代码了吗? PM 如何从context 获取数据?
  • `return context.getSharedPreferences(getDefaultSharedPreferencesName(context), getDefaultSharedPreferencesMode());``

标签: java android mockito sharedpreferences


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    所以你需要模拟对PreferenceManager.getDefaultSharedPreferences(context) 的静态调用。目前使用 mockito 是不可能的,还有discussion going on the corresponding issue

    this question 接受的答案中显示了一种解决方案,您可以检查PowerMockJMockit 作为替代方案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 2018-10-29
      • 1970-01-01
      • 2019-06-13
      • 2012-01-02
      相关资源
      最近更新 更多