對於某些無法解釋的原因,我在構造函數中指定的字段(currentExp
)在我的unittest中使用模擬時未正確設置。我正在通過使用我的Storage
類(使用SharedPreferences)通過loadExperience
方法加載它來指定字段currentExp
。當我在單元測試這一點,我想嘲笑Storage
類,所以loadexperience
返回的10使用模擬和抽象類時未設置字段值
值這裏是我的具體Experience
類:
public class Experience extends StorageObject {
private int currentExp = 0;
public Experience() {
this(new Storage());
}
@VisibleForTesting
protected Experience(Storage storage) {
super(storage);
} // Debug point #2
@Override
protected void init(Storage storage) {
this.currentExp = storage.loadExperience();
} // Debug point #1
}
它擴展StorageObject
:
public abstract class StorageObject {
protected Storage storage;
protected StorageObject() {
this(new Storage());
}
@VisibleForTesting
protected StorageObject(Storage storage) {
this.storage = storage;
init(storage);
}
protected abstract void init(Storage storage);
}
這是我的單元測試:
@Test
public void testConstructor_StorageValuePositive_IsSetAsCurrentExp() {
int expectedSavedExp = 10;
Storage storageMock = mock(Storage.class);
doReturn(expectedSavedExp).when(storageMock).loadExperience();
Experience exp = new Experience(storageMock);
assertEquals(expectedSavedExp, exp.getCurrentExp());
}
在調試過程中,我發現模擬DOES工作,並且在調試點#1處將10的值分配給currentExp
。然後不久之後,在調試點#2,該值似乎再次爲0。
任何人都知道這裏發生了什麼,以及如何解決這個問題?
很好,謝謝! 我想你的意思是'currentExp'而不是'expectedSavedExp'? ;-) 但我知道如何解決這個問題,這纔是最重要的。 ... 另一個想法:因爲我在'StorageObject'中設置了'storage'作爲一個字段,所以我可以用'storage.loadExperience()'初始化'currentExp'作爲默認值,而不是在構造函數中賦值。這樣我也可以省略'abstract init'方法。 似乎解決了單元測試問題,但這樣做是否通用/正確? –
ups是的,我的意思是currentExp。你可以將init移動到子類中,沒有理由將它放在父類上。 – jbarat