我无法使用Mockito测试SharedPreference

时间:2019-02-05 06:39:44

标签: android testing mockito preferences

我无法模拟sharedPreference,当我测试演示者时,sharepreference实例为空。

@RunWith(MockitoJUnitRunner.class)
public class PreferencesPresenterTest {

    @Mock
    PreferencesMvpView preferencesMvpView;

    @Mock
    ApiService apiService;

    @Mock
    Context context;

    @Mock
    SchedulerProvider mSchedulerProvider;

    PreferencesPresenter mPresenter;


    @Before
    public void setUp() throws Exception {

        CompositeDisposable compositeDisposable = new CompositeDisposable();
        mPresenter = new PreferencesPresenter(compositeDisposable, apiService, mSchedulerProvider);


        // mPrefences = new AppPreferences();
        mPresenter.onAttach(preferencesMvpView);

    }

    @Test
    public void testFilter() throws Exception {
        Mockito.when(mSchedulerProvider.getUiScheduler()).thenReturn(Schedulers.trampoline());
        Mockito.when(mSchedulerProvider.getWorkerScheduler()).thenReturn(Schedulers.trampoline());


        mPresenter.loadPreferenceData();
    }


}

//这是我正在测试的方法

@Override
    public void loadPreferenceData() {

        long userId = mPreferences.getLong(AppPreferences.USER_ID);
        getMvpView().showLoading();

        getCompositeDisposable().add(getApiService().getPreferencesData(userId)
                .subscribeOn(getSchedulerProvider().getWorkerScheduler())
                .observeOn(getSchedulerProvider().getUiScheduler())
                .subscribe(
                        jsonObject -> {
                            //Log.d(getClass().getSimpleName(), "PreferencesPresenter : loadPreferenceData: onSuccess");
                            if (!isViewAttached()) {
                                return;
                            }

                            getMvpView().hideLoading();
                            if (jsonObject != null && AppUtils.containsValue(jsonObject, JsonKeys.DATA))
                                setupFieldList(new Gson().fromJson(jsonObject.get(JsonKeys.DATA), Preferences.class));
                        }
                        , throwable -> {
                            // Log.d(getClass().getSimpleName(), "PreferencesPresenter : loadPreferenceData: Error");
                            if (!isViewAttached()) {
                                return;
                            }

                            getMvpView().hideLoading();
                            handleApiError(throwable);
                        }));
    }

1 个答案:

答案 0 :(得分:0)

您是否正在运行单元测试?默认情况下,在单元测试中对Android框架的任何调用都会引发异常。

来自https://developer.android.com/training/testing/fundamentals#interact-android-environment

  

您可以通过针对未包含任何代码的修改版android.jar运行单元测试来控制和验证与应用程序交互的Android框架的元素。由于默认情况下,您的应用程序对Android框架的调用会引发异常,因此您需要使用模拟框架(例如Mockito)来消除所有这些交互。

您在这里有几个选择:

  1. 在单独的类中封装与SharedPreferences进行交互的代码,并在测试Presenter时使用Mockito模拟该类。
  2. 使用Robolectric,它提供了Android SDK的实现
  3. 运行测试(androidTest)而非单元测试(test

我建议使用#1,因为这种方法可以让您继续运行快速的JUnit测试,而不必处理Robolectric的开销。