webentwicklung-frage-antwort-db.com.de

Die Verwendung von PowerMockito.whenNew () wird nicht verspottet und die ursprüngliche Methode wird aufgerufen

Ich habe einen Code wie folgt:

Class A {
  public boolean myMethod(someargs) {
    MyQueryClass query = new MyQueryClass();
    Long id = query.getNextId();
    // some more code
  }
}
Class MyQueryClass     {
  ....
  public Long getNextId() {
    //lot of DB code, execute some DB query
    return id;
  }
}

Jetzt schreibe ich einen Test für A.myMethod(someargs). Ich möchte die echte Methode query.getNextId() überspringen und stattdessen einen Stub-Wert zurückgeben. Grundsätzlich möchte ich MyQueryClass verspotten.

In meinem Testfall habe ich also Folgendes verwendet:

MyQueryClass query = PowerMockito.mock(MyQueryClass.class);
PowerMockito.whenNew(MyQueryClass.class).withNoArguments().thenReturn(query);
when(query.getNextId()).thenReturn(1000000L);

boolean b = A.getInstance().myMethod(args);

//asserts

Ich habe @RunWith(PowerMockRunner.class) und @PrepareForTest({MyQueryClass.class}) zu Beginn meiner Testklasse verwendet.

Wenn ich jedoch den Test debugge, ruft er immer noch die echte Methode getNextId() der MyQueryClass-Klasse auf.

Was fehlt mir hier? Kann jemand helfen, da ich neu bei Mockito und PowerMockito bin.

64
user3942446

Sie müssen die Klasse, in der der Konstruktor aufgerufen wird , in die Annotation @PrepareForTest Anstelle der Klasse einfügen, die erstellt wird - siehe - Scheinkonstruktion neuer Objekte .

In deinem Fall:

@PrepareForTest(MyQueryClass.class)

@PrepareForTest(A.class)

Allgemeiner:

@PrepareForTest(NewInstanceClass.class)

@PrepareForTest(ClassThatCreatesTheNewInstance.class)

163
TrueDub

Wie @TrueDub in seiner akzeptierten Antwort erwähnt, müssen Sie die Klasse, in der der Konstruktor aufgerufen wird, zum @PrepareForTest hinzufügen. 

Wenn Sie dies tun, ist die Abdeckung für diese Klasse, wie von Eclemma und Sonar berichtet, für diese Klasse gleich Null

Powermockito Wiki

Wir werden Javassist durch ByteBuddy (# 727) ersetzen und es sollte helfen, dieses alte Problem zu lösen. Aber jetzt gibt es KEINE VERWENDUNG PowerMock mit JaCoCo On-the-Fly-Instrumentierung. Und keine Problemumgehung für Code-Abdeckung in IDE abrufen.

Die Lösung hier wäre also, den eigentlichen Code so umzuwandeln, dass eine statische Factory verwendet wird, die eine Instanz dieser Klasse zurückgibt und diese statisch mockt.

1
ACV