使用Mockito了解SharedPreference行为

时间:2016-07-26 09:58:06

标签: android junit mocking sharedpreferences mockito

我在测试模拟对象时遇到问题,特别是在我自己编写的类以及SharedPreferences模拟器上。我从我参与的应用程序中提取了一个代码片段,并对其进行了简化,以便了解正在发生的事情。

我的项目中有以下gradle设置:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"

    defaultConfig {
        applicationId "de.mk_xappo.mockitoexample"
        minSdkVersion 19
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    testCompile 'org.mockito:mockito-core:1.10.19'
    compile 'com.android.support:appcompat-v7:24.1.1'
}

我在这里上课了:

package de.mk_xappo.mockitoexample;

import android.content.SharedPreferences;


public class FeedbackManager {

    protected static final String RATED = "RATED";

    private final SharedPreferences sharedPreferences;


    public FeedbackManager(SharedPreferences sharedPreferences) {
        this.sharedPreferences = sharedPreferences;
    }

    protected void setRated() {
        sharedPreferences.edit().putBoolean(RATED, true).commit();
    }

    protected boolean getRated() {
        return sharedPreferences.getBoolean(RATED, false);
    }

    protected static boolean getTrue() {
        return true;
    }

    public boolean getFalse() {
        return false;
    }
}

我有这个测试课:

package de.mk_xappo.mockitoexample;

import android.app.Application;
import android.content.SharedPreferences;

import org.junit.Assert;
import org.junit.Test;

import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class FeedbackManagerTest {

    private Application applicationMock;
    private SharedPreferences preferencesMock;
    private SharedPreferences.Editor editorMock;
    private FeedbackManager feedbackManager;

    @org.junit.Before
    public void setUp() throws Exception {
        applicationMock = mock(Application.class);
        preferencesMock = mock(SharedPreferences.class);

        when(applicationMock.getSharedPreferences(anyString(), anyInt())).thenReturn(preferencesMock);

        editorMock = mock(SharedPreferences.Editor.class);

        when(editorMock.putBoolean(anyString(), anyBoolean())).thenReturn(editorMock);
        when(editorMock.putLong(anyString(), anyLong())).thenReturn(editorMock);
        when(editorMock.remove(anyString())).thenReturn(editorMock);
        when(preferencesMock.edit()).thenReturn(editorMock);

//        feedbackManager = new FeedbackManager(preferencesMock);
        feedbackManager = mock(FeedbackManager.class);
    }

    @Test
    public void testBoolean() throws Exception {
        Assert.assertTrue(FeedbackManager.getTrue());
        Assert.assertFalse(feedbackManager.getFalse());
    }

    @Test
    public void testSetRated() throws Exception {
        boolean rated = feedbackManager.getRated();
        Assert.assertFalse(rated);
        feedbackManager.setRated();

        rated = feedbackManager.getRated();

        when(preferencesMock.getBoolean(FeedbackManager.RATED, false)).thenReturn(false);
        when(preferencesMock.getBoolean(FeedbackManager.RATED, false)).thenReturn(true);

        Assert.assertFalse(rated);
        Assert.assertTrue(rated);
    }
}

现在,我不明白的是,如果我运行testBoolean(),一切都按预期工作。但是如果我运行testSetRated()两件事,按预期工作。

因为 when(preferencesMock.getBoolean(FeedbackManager.RATED, false)).thenReturn(false); when(preferencesMock.getBoolean(FeedbackManager.RATED, false)).thenReturn(true);都失败了,尽管它们相反。

我不明白为什么Assert.assertFalse(rated); 有效Assert.assertTrue(rated); 失败。这应该是相反的。

也许我误解了模拟的用法,特别是SharedPreferences模拟?或者出了什么问题?

1 个答案:

答案 0 :(得分:0)

我真的误解了when(mock.method()).thenReturn(value)是如何运作的。它没有检查任何东西。它只表示如果下次调用mockvalue对象将返回method()。也可以通过查看是否已编写testSetRated()来测试SharedPreferences方法。然后一切都按预期工作。