我在測試模擬對象時遇到問題,特別是在我自寫的類以及SharedPreferences模擬上。我從我參與的應用程序中提取了一段代碼片段,並將其簡化爲了解正在發生的事情。瞭解使用Mockito的SharedPreference行爲
我有我的項目中的下列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);
失敗。這應該是相反的。
也許我誤解了mock的用法,尤其是SharedPreferences mocks?或者出了什麼問題?