2013-02-04 1 views
6

ich Mockito bin mit einer Klasse zu verspotten, die eine Methode hat, die etwa wie folgt aussieht:prüfen Konsistenz von mehreren Argumenten Mockito

setFoo(int offset, float[] floats) 

Ich möchte überprüfen können, dass die Werte im Array (floats) sind (innerhalb einer gegebenen Toleranz) gleich den Werten in einem Array von erwarteten Werten.

Der Haken ist, dass ich den Inhalt von floats beginnend an der von offset angegebenen Position überprüfen möchte. Für den Zweck des Tests weiß ich nicht, was der Offset ist, solange er auf die Werte zeigt, die ich erwarte. Es ist mir auch egal, was der Rest des Arrays enthält. Ich interessiere mich nur für die Werte beginnend mit dem gelieferten Offset.

Wie mache ich das?

+0

Vielleicht ist es nur ich, aber ich verstehe Ihre Frage nicht ganz. Was ist das Problem mit dem Schreiben einer eigenen Methode, die Offset und 2 Arrays als Argumente akzeptiert und prüft, ob die Elemente in diesen Arrays vom Offset an gleich sind? –

+0

@AndrewLogvinov Wie schreibe ich meine eigene Methode auf ein Mockito-Mock-Objekt? –

+0

Ich glaube nicht, dass du es auch tun solltest. Nach dem Aufruf von 'setFoo()' erwarten Sie, dass sich der Status des Objekts geändert hat. Sie sollten also den Zustand des Objekts abfragen und mit Ihren Werten vergleichen. Ein Code-Snippet wäre hilfreich, um das Problem besser zu verstehen. –

Antwort

17

Während ein Teil mock Sie keine schlechte Idee ist, verwenden, Vielleicht finden Sie Ihren Code einfacher zu folgen, wenn Sie stattdessen einen ArgumentCaptor verwenden, um die Werte nach der Tat zu erhalten. Es ist ein spezieller Argument-Matcher, der den passenden Wert verfolgt.

// initialized with MockitoAnnotations.initMocks(); 
@Captor ArgumentCaptor<Integer> offsetCaptor; 
@Captor ArgumentCaptor<float[]> floatsCaptor; 
@Mock Bar bar; 

@Test 
public void valuesShouldBeCloseEnough() { 
    Sut sut = new Sut(bar); 
    sut.doSomething(); 
    verify(bar).setFoo(offsetCaptor.capture(), floatsCaptor.capture()); 

    // check values with assertValuesAreCloseEnough, declared elsewhere 
    assertValuesAreCloseEnough(offsetCaptor.getValue(), floatsCaptor.getValue()); 
} 
+0

Das macht genau das, was ich brauche. Vielen Dank! –

1

Sie möchten ein partial mock. Nehmen wir an, dass die Klasse, setFoo() hat, ist Bar genannt:

private static abstract class AssertingBar implements Bar { 

    @Override 
    void setFoo(int offset, float[] floats) { 
    this.offset = offset; 
    this.floats = floats 
    } 

    public void verify(float[] expectedFloats, float delta) { 
    // do your verification here 
    } 
} 

@Test 
public void valuesShouldBeCloseEnough() { 
    AssertingBar bar = Mockito.mock(AssertingBar.class, Mockito.CALLS_REAL_METHODS); 

    Sut sut = new Sut(bar); 
    sut.doSomething(); 

    bar.verify(...); 
} 

Wenn Bar eine Klasse ist, nicht eine Schnittstelle, dann können Sie doCallRealMethod()

+0

'Mockito.CALLS_REAL_METHODS' schien nicht mit einer Schnittstelle zu funktionieren. Ich bekam ständig Fehler beim Versuch, eine echte Methode an einer Schnittstelle aufzurufen. Ich machte einige Fortschritte mit 'doCallRealMethod()', aber der Argument-Captor-Ansatz, der in einer anderen Antwort vorgeschlagen wurde, war einfacher zu arbeiten und erforderte viel weniger Code für diesen speziellen Fall. Danke trotzdem. –