由于某些无法解释的原因,我在构造函数中分配的字段(currentExp
)在使用模拟器进行单元测试时未正确设置。我是通过使用我的currentExp
类(使用SharedPreferences)通过loadExperience
方法加载字段Storage
来分配字段的。当我对此进行单元测试时,我想模拟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。
任何人都知道这里发生了什么,以及如何解决这个问题?
答案 0 :(得分:1)
这里的问题是初始化顺序。超级构造函数首先发生,然后是字段初始化。
因此,你的构造函数将require(BASE."template/head.php");
中的currentExp
设置为超级调用,然后该字段将被启动为0。
那你能做什么?一些想法:
将currentExp
移至父类,或者不要为其提供默认值。
更多阅读材料:
http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.5