J'ai trouvé cela en essayant de résoudre un problème similaire en créant un moignon Mockito avec un paramètre Map. Je ne voulais pas écrire un matcher personnalisé pour la carte en question, puis j'ai trouvé une solution plus élégante: utiliser les matchers supplémentaires hamcrest-library avec argThat de Mockito:
when(mock.search(argThat(hasEntry("xpath", "PRICE"))).thenReturn("$100.00");
Si vous devez vérifier contre plusieurs entrées puis vous pouvez utiliser d'autres goodies hamcrest:
when(mock.search(argThat(allOf(hasEntry("xpath", "PRICE"), hasEntry("otherKey", "otherValue")))).thenReturn("$100.00");
Cela commence à être longue avec des cartes non triviales, donc je fini par extraire les méthodes pour recueillir les matchers d'entrée et les coincés dans nos 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()]);
}
Je me reste:
when(mock.search(argThat(matchesEntriesIn(map))).thenReturn("$100.00");
when(mock.search(argThat(matchesAnyEntryIn(map))).thenReturn("$100.00");
Il y a une certaine laideur associée aux médicaments génériques et je suis supprimer un avertissement, mais au moins il est sec et nichés dans le TestUtil. Une dernière note, faites attention à embedded hamcrest issues in JUnit 4.10. Avec Maven, je recommande d'abord d'importer hamcrest-library puis JUnit 4.11 (maintenant 4.12) et d'exclure hamcrest-core de JUnit pour faire bonne mesure:
<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 septembre 2017 - Par certains des commentaires, je mis à jour ma réponse pour montrer ma dépendance Mockito, mes importations l'util de test, et un JUnit qui est en cours d'exécution vert d'aujourd'hui:
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);
}
}
}
Il manque une patte de fermeture. – stefanglase
IOurXMLDocument représente notre couche de service que je ne veux pas appeler pour mes tests unitaires. Pour une situation, nous l'appelons deux fois avec deux valeurs de carte différentes. Au lieu de cela, je veux inspecter la valeur et retourner un résultat fixe. Ainsi, lorsque le code de l'application est le suivant: map.put ("xpath", "PRODUCTNAME"); quand (mock.search (map)) then thenReturn ("Candybar"); – Sean
Ne devrait pas être mock.search (eq (map)) afin de vérifier l'égalité réelle de la carte? – fikovnik