mit dem folgenden Code:Mockito - Mocking Betonklassen
LinkedList list = mock(LinkedList.class);
doCallRealMethod().when(list).clear();
list.clear();
durch diesen Test ausführen, eine Nullpointer von der ersten Zeile in LinkedList # klar geworfen wird:
public void clear() {
Entry<E> e = header.next;
while (e != header) {
Entry<E> next = e.next;
//Code omitted.
aber Header wurde instanziiert vor:
private transient Entry<E> header = new Entry<E>(null, null, null);
Könnte etwas Bitte erklären Sie, was während der Mock-Erstellung passiert.
####### UPDATE. ######
Nachdem ich alle Antworten gelesen habe, habe ich in Objesisis Quellcode geschaut und herausgefunden, dass Reflection API verwendet wird, um die Proxy Instanz (über CGLIB) zu erstellen und somit alle Konstruktoren in der Hierarchie zu umgehen bis java.lang.Object.
Hier ist der Beispielcode um das Problem zu simulieren:
public class ReflectionConstructorTest {
@Test
public void testAgain() {
try {
//java.lang.Object default constructor
Constructor javaLangObjectConstructor = Object.class
.getConstructor((Class[]) null);
Constructor mungedConstructor = ReflectionFactory
.getReflectionFactory()
.newConstructorForSerialization(CustomClient.class, javaLangObjectConstructor);
mungedConstructor.setAccessible(true);
//Creates new client instance without calling its constructor
//Thus "name" is not initialized.
Object client = mungedConstructor.newInstance((Object[]) null);
//this will print "CustomClient"
System.out.println(client.getClass());
//this will print "CustomClient: null". name is null.
System.out.println(client.toString());
} catch(Exception e) {
e.printStackTrace();
}
}
}
class CustomClient {
private String name;
CustomClient() {
System.out.println(this.getClass().getSimpleName() + " - Constructor");
this.name = "My Name";
}
@Override
public String toString() {
return this.getClass().getSimpleName() + ": " + name;
}
}
zeigen Sie uns full stacktrace – Archer