Aus irgendeinem unerklärlichen Grund ein Feld (currentExp
) ich im Konstruktor zuweisen ist nicht korrekt festgelegt, während ein Mock für meine Unittest verwendet. Ich gebe das Feld currentExp
durch Laden über die loadExperience
Methode unter Verwendung meiner Storage
Klasse (die SharedPreferences verwendet). Wenn ich dies Unittesting, würde Ich mag die Storage
Klasse verspotten, so kehrt loadexperience
ein Wert von 10.Feldwert nicht festgelegt, wenn Mock und abstrakte Klasse verwendet
Hier ist meine konkrete Experience
Klasse:
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
}
Es erstreckt sich 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);
}
Und das ist mein Unittest:
@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());
}
Während des Debuggens habe ich festgestellt, dass die Mock DOES funktioniert, und der Wert 10 ist currentExp
am Debug-Punkt # 1 zugewiesen. Kurz danach, am Debug-Punkt # 2, scheint der Wert wieder 0 zu sein.
Wer hat eine Ahnung, was hier passiert und wie man dieses Problem löst?
Großartig, danke! Ich denke du meinst 'currentExp' statt' expectedSavedExp'? ;-) Aber ich habe die Idee, wie man es löst, darauf kommt es an. ... Eine andere Idee: Weil ich 'Speicher' als ein Feld in 'StorageObject' eingestellt habe, könnte ich' currentExp' auch mit 'storage.loadExperience()' als Standardwert initialisieren, anstatt es im Konstruktor zuzuweisen . Auf diese Weise kann ich auch die Methode der "abstrakten Init" weglassen. Das scheint das unitest Problem zu lösen, aber ist es üblich/richtig das zu tun? –
ups ja ich meinte currentExp. Sie könnten einfach die Init in die Kindklasse verschieben, es gibt keinen Grund dafür, dass sie auf der Elternklasse ist. – jbarat