Ich habe versucht, ein ähnliches Problem zu lösen, indem ich einen Mockito-Stub mit einem Map-Parameter erstelle. Ich wollte nicht einen benutzerdefinierten Matcher für die Karte in Frage schreiben und dann fand ich eine elegantere Lösung: Verwenden Sie die zusätzlichen Matcher in hamcrest-library mit Mockito der argThat:
when(mock.search(argThat(hasEntry("xpath", "PRICE"))).thenReturn("$100.00");
Wenn Sie gegen mehrere Einträge überprüfen, müssen dann Sie können andere hamcrest Leckereien verwenden:
when(mock.search(argThat(allOf(hasEntry("xpath", "PRICE"), hasEntry("otherKey", "otherValue")))).thenReturn("$100.00");
Diese lange mit nicht-trivialen Karten zu bekommen beginnt, so dass ich am Ende Methoden Extrahieren der Eintrag Matcher zu sammeln und steckte sie in unserem TestUtils:
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.hasEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.hamcrest.Matcher;
---------------------------------
public static <K, V> Matcher<Map<K, V>> matchesEntriesIn(Map<K, V> map) {
return allOf(buildMatcherArray(map));
}
public static <K, V> Matcher<Map<K, V>> matchesAnyEntryIn(Map<K, V> map) {
return anyOf(buildMatcherArray(map));
}
@SuppressWarnings("unchecked")
private static <K, V> Matcher<Map<? extends K, ? extends V>>[] buildMatcherArray(Map<K, V> map) {
List<Matcher<Map<? extends K, ? extends V>>> entries = new ArrayList<Matcher<Map<? extends K, ? extends V>>>();
for (K key : map.keySet()) {
entries.add(hasEntry(key, map.get(key)));
}
return entries.toArray(new Matcher[entries.size()]);
}
einige Hässlichkeit in der TestUtil mit den Generika assoziiert Es gibt und ich unterdrückt eine Warnung, aber zumindest ist es trocken und versteckt
when(mock.search(argThat(matchesEntriesIn(map))).thenReturn("$100.00");
when(mock.search(argThat(matchesAnyEntryIn(map))).thenReturn("$100.00");
:
Also ich bin mit links.
Eine letzte Anmerkung, hüten Sie sich die embedded hamcrest issues in JUnit 4.10. Mit Maven empfehle ich zuerst hamcrest-library und dann JUnit 4.11 (jetzt 4.12) und verstehen sich inklusive hamcrest-Kern von JUnit nur für eine gute Maßnahme:
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
Edit: 1. September 2017 - Per einige der Kommentare, aktualisiert ich meine Antwort meine Mockito Abhängigkeit zu zeigen, meine Importe der Test util und eine junit, die grün wie heute läuft:
import static blah.tool.testutil.TestUtil.matchesAnyEntryIn;
import static blah.tool.testutil.TestUtil.matchesEntriesIn;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
public class TestUtilTest {
@Test
public void test() {
Map<Integer, String> expected = new HashMap<Integer, String>();
expected.put(1, "One");
expected.put(3, "Three");
Map<Integer, String> actual = new HashMap<Integer, String>();
actual.put(1, "One");
actual.put(2, "Two");
assertThat(actual, matchesAnyEntryIn(expected));
expected.remove(3);
expected.put(2, "Two");
assertThat(actual, matchesEntriesIn(expected));
}
@Test
public void mockitoTest() {
SystemUnderTest sut = mock(SystemUnderTest.class);
Map<Integer, String> expected = new HashMap<Integer, String>();
expected.put(1, "One");
expected.put(3, "Three");
Map<Integer, String> actual = new HashMap<Integer, String>();
actual.put(1, "One");
when(sut.search(argThat(matchesAnyEntryIn(expected)))).thenReturn("Response");
assertThat(sut.search(actual), is("Response"));
}
protected class SystemUnderTest {
// We don't really care what this does
public String search(Map<Integer, String> map) {
if (map == null) return null;
return map.get(0);
}
}
}
Es ist ein Schließbügel fehlt. – stefanglase
IOurXMLDocument steht für unsere Serviceebene, die ich für meine Komponententests nicht aufrufen möchte. Für 1 Situation rufen wir sie zweimal mit 2 verschiedenen Kartenwerten an. Stattdessen möchte ich den Wert überprüfen und ein festes Ergebnis zurückgeben. Also, wenn der Anwendungscode folgendes tut: map.put ("xpath", "PRODUCTNAME"); when (mock.search (map)). ThenReturn ("Candybar"); – Sean
Sollte nicht mock.search (eq (map)) sein, damit es die tatsächliche Kartengleichheit überprüft? – fikovnik