tl; dr: Diese Tests werden nicht kompiliert, da die Typparameter nicht übereinstimmen. Welche Änderungen sollte ich vornehmen, damit sie kompilieren und korrekt ausführen?Mockito, argThat und hasEntry
Ich habe einige Nicht-Test-Code, der in einen Dienst aufruft. Es ruft die activate-Methode des Dienstes mit einem map-Parameter auf.
public class Foo {
private final Service service;
public Foo(Service service) {
this.service = service;
}
public void bar() {
Map<String, ?> params = getParams();
service.activate(params);
}
private Map<String, ?> getParams() {
// something interesting goes here
}
}
Einige Code, den ich zu Test bin versucht hat eine Abhängigkeit von einem Dienst wie diese:
public interface Service {
public void activate(Map<String, ?> params);
}
Ich möchte diesen Code testen, indem Sie den Dienst mit Mockito und Verifizieren verspotten, die aktivieren wurde mit einer vernünftigen Karte aufgerufen. Der folgende Code funktioniert:
@Test
public void testExactMap() {
Service mockService = mock(Service.class);
Foo foo = new Foo(mockService);
foo.bar();
Map<String, String> expectedParams = new HashMap<>();
expectedParams.put("paramName", "paramValue");
verify(service).activate(expectedParams);
}
Allerdings möchte ich nur testen, dass die Karte einen bestimmten Eintrag enthält. Die hamcrest hasEntry matcher scheint perfekt für diesen Anwendungsfall:
@Test
public void testHasEntry() {
Service mockService = mock(Service.class);
Foo foo = new Foo(mockService);
foo.bar();
verify(mockService).activate(argThat(hasEntry("paramName", "paramValue")));
}
Wenn ich das versuche, erhalte ich folgende Fehlermeldung in IntelliJ IDEA:
Error:(31, 45) java: incompatible types: inference variable T has incompatible bounds
equality constraints: java.util.Map<? extends java.lang.String,? extends java.lang.String>
upper bounds: java.util.Map<java.lang.String,?>,java.lang.Object
Das Problem hier ist, dass ich eine Mockito Matcher von Map<String, ?>
brauchen , aber hasEntry gibt mir einen Matcher von Map<? extends String, ? extends String>
. Selbst mit expliziten Typparametern kann ich nicht herausfinden, was zu tun ist, um den "? Extends" -Teil des Typparameters abzustimmen. Was muss ich tun, um diesen Fehler zu beheben? Gibt es einen bestimmten Cast- oder expliziten Typparameter, den ich verwenden sollte?
Ich verstehe, dass ich ArgumentCaptor dafür verwenden kann. Ist das wirklich der einzige Weg, dies zu tun? Ist das überhaupt möglich mit Hamcrest Matcher?
Zuerst hatte ich die falsche Code-Schnipsel auf. Es tut uns leid! Jetzt korrigiert. Zweitens funktioniert das nicht. Service.activate erwartet 'Map', aber der Platzhalter ist in der Besetzung nicht erlaubt. Das Ersetzen von '?' Durch 'Object' funktioniert auch nicht. –
Wesley
Können Sie Testcode einschließlich Imports teilen? – VinPro
Ich habe einen Link zu einem Beispielprojekt zu der Frage hinzugefügt. – Wesley