我在测试mock对象时遇到了问题,尤其是在我自己编写的类以及SharedPreferences mock上。我从我参与的应用程序中提取了一段代码片段,并对其进行了简化,以了解发生了什么
我的项目中有以下等级设置:
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 mock?或者出了什么问题?
我真的误解了when(mock.method()).thenReturn(value)
的工作原理。它不检查任何内容。它只是说,如果下次调用method()
,mock
对象将返回value
。testSetRated()
方法也可以通过查看是否已经编写了SharedPreferences
来进行测试。然后一切都按预期进行。