Frage

Gibt es eine saubere Methode eine Klasse mit generischen Parametern von spöttischen? Sagen wir, ich habe eine Klasse Foo<T> verspotten, die ich brauche, in eine Methode zu übergeben, die eine Foo<Bar> erwartet. Ich kann die folgende leicht genug tun:

Foo mockFoo = mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());

Unter der Annahme, getValue() gibt die generischen Typen T. Aber das wird Kätzchen haben, wenn ich es später passieren in ein Verfahren erwartet Foo<Bar>. Wirft das einzige Mittel, dies zu tun?

War es hilfreich?

Lösung

Ich glaube, Sie brauchen es zu werfen, aber es sollte nicht allzu schlecht sein:

Foo<Bar> mockFoo = (Foo<Bar>) mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());

Andere Tipps

Eine andere Möglichkeit, um dies stattdessen @Mock Anmerkung zu verwenden. Nicht in allen Fällen funktionieren, sieht aber viel sexier:)

Hier ist ein Beispiel:

@RunWith(MockitoJUnitRunner.class)
public class FooTests {

    @Mock
    public Foo<Bar> fooMock;

    @Test
    public void testFoo() {
        when(fooMock.getValue()).thenReturn(new Bar());
    }
}

Die MockitoJUnitRunner initialisiert die Felder mit Anmerkungen versehen mit @Mock .

Sie können immer eine Zwischenklasse / Schnittstelle erstellen, die den generischen Typ genügen würde, die Sie angeben wollen, sind. Zum Beispiel, wenn Foo eine Schnittstelle ist, konnte man die folgende Schnittstelle in Ihrer Testklasse erstellen.

private interface FooBar extends Foo<Bar>
{
}

In Situationen, in denen Foo sind ein Nicht-final Klasse, Sie könnten nur die Klasse mit dem folgenden Code erweitern und das gleiche tun:

public class FooBar extends Foo<Bar>
{
}

Dann könnte man eine der obigen Beispiele mit dem folgenden Code verbrauchen:

Foo<Bar> mockFoo = mock(FooBar.class);
when(mockFoo.getValue()).thenReturn(new Bar());

Erstellen Sie eine Testprogramm Methode . Besonders nützlich, wenn Sie es für mehr als einmal benötigen.

@Test
public void testMyTest() {
    // ...
    Foo<Bar> mockFooBar = mockFoo();
    when(mockFooBar.getValue).thenReturn(new Bar());

    Foo<Baz> mockFooBaz = mockFoo();
    when(mockFooBaz.getValue).thenReturn(new Baz());

    Foo<Qux> mockFooQux = mockFoo();
    when(mockFooQux.getValue).thenReturn(new Qux());
    // ...
}

@SuppressWarnings("unchecked") // still needed :( but just once :)
private <T> Foo<T> mockFoo() {
    return mock(Foo.class);
}

Hier ist ein interessanter Fall: Methode generische Sammlung receieves und gibt allgemeine Sammlung von gleichem Basistyp. Zum Beispiel:

Collection<? extends Assertion> map(Collection<? extends Assertion> assertions);

Dieses Verfahren kann mit Kombination von Mockito anyCollectionOf Matcher und der Antwort verspottet werden.

when(mockedObject.map(anyCollectionOf(Assertion.class))).thenAnswer(
     new Answer<Collection<Assertion>>() {
         @Override
         public Collection<Assertion> answer(InvocationOnMock invocation) throws Throwable {
             return new ArrayList<Assertion>();
         }
     });

Ich bin damit einverstanden, dass man sollte nicht Warnungen in Klassen oder Methoden unterdrückt als eine andere, zufällig unterdrückt Warnungen übersehen könnte. Aber meiner Meinung nach ist es absolut sinnvoll, eine Warnung zu unterdrücken, die nur eine einzige Zeile Code auswirkt.

@SuppressWarnings("unchecked")
Foo<Bar> mockFoo = mock(Foo.class);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top