Mockito/PowerMock: wie setzen Sie verspottet statische variable im SUT?

Ich hasse einzuführen Unit-tests in ein legacy-code-Basis, aber ich muss.

Bis jetzt habe ich erfolgreich eingeführten unit-Tests in den legacy-code-Basis, die mit Mockito und PowerMock. Funktionierte perfekt, bis ich traf mich mit dieser situation:

in der SUT, es sind mehrere statische Variablen (die ich verspottet mit Hilfe von PowerMock, Spott statische Methoden und Spott Konstruktoren).

Jetzt in der ersten test-Methode, die alle fein gearbeitet und verspottet static var zurückgegeben, die erwartete Ausgabe Wert.

aber in der anschließenden test-Methoden, die verspottet statisches Objekt immer wieder Wert, wurde beim ersten test, obwohl ich ihn rufen Sie reset() auf, bevor Sie die tests.

//legacy code base:
public class SUT {
  private static Collaborator1 c1 = null;
  private static Collaborator2 c2 = null;

  public SUT(param1) {
    if (c1 == null) {
        c1 = Collaborator1.instance(param1);
        c2 = new Collaborator2(c1);
    } else {
    }
  }
}



//newly introduced unit tests:
@RunWith(PowerMockRunner.class)
@PrepareForTest({
    SUT.class,                  //to mock: new Collaborator2(..), as required by PowerMock when mocking constructors
    Collaborator1.class,        //to mock: Collaborator1.instance(..), as required by PowerMock in mocking static methods
})
public class SUTTest {

  private SUT sut;

  private Collaborator1 c1 = mock(Collaborator1.class);
  private Collaborator2 c2 = mock(Collaborator2.class);

  @Before  
  public void setup() {
    //mock c1:
    PowerMockito.mockStatic(Collaborator1.class);
    when(Collaborator1.instance(param1)).thenReturn(c1);

    //mock c2:
    PowerMockito.whenNew(Collaborator2.class).withArguments(c1).thenReturn(c2);

    reset(c1);
    reset(c2);

    sut = new SUT(param1);
  }

  @Test
  public void test1() {
    when(c2.foo(input1)).thenReturn(out1); 

    //do something
  }

  @Test
  public void test2() {
    when(c2.foo(input2)).thenReturn(out2);    //BANG!!! c2.foo(input2) always return "out1"

    //do something
  }
}

Da der Konstruktor der SUT nur instanziiert c1 und c2, wenn die statische c1 ist null, Sie (c1, c2) nicht bekommen, re-instanziiert in sub-Sequenz nennt. Was ich nicht verstehe, ist, warum reset(c1), reset(c2) haben keine Wirkung in test2?

Irgendeine Idee?

Haben Sie versucht manuell zurücksetzen c1 auf null mit der Spiegelung in einer @After-Methode?
Ich habe versucht, das zurücksetzen c1 auf null in der @Before-Methode, sollte den gleichen Effekt haben? Wie auch immer,ich gebe mal einen Versuch @Nach. Btw, die Leistung des tests wurde sehr schlecht, nachdem die Einführung von Mockito & PowerMock. Ein einfacher test dauert mehr als 10 min.
kein Glück mit @Nach, ich habe versucht, das zurücksetzen c1, c2 und sut zu null in die @After-Methode. Aber aus der debug-Sitzung, fand ich, dass vor test2, im Konstruktor des SUT, c1 ist immer noch NICHT null.
Was willst du testen, geschieht mit C1 und c2? Ich würde wahrscheinlich lassen sich die statischen Spott und einfach mock c1 und c2, die Sie getan haben, und dann setzen Sie statisch auf meine alte test-Klasse mit der spiegelung in der test-Methode selbst. Ich glaube nicht, beneide dich für den Umgang mit dieser fiesen legacy-code!
Btw... ich hatte noch nie performance-Probleme mit Mockito (aber ich habe nicht verwendet, PowerMock).

InformationsquelleAutor Tumer | 2011-04-26

Schreibe einen Kommentar