tl; dr:這些測試不編譯,因爲類型參數不匹配。我應該做些什麼改變才能使它們正確編譯並運行 ?Mockito,argThat和hasEntry
我有一些在調用服務非測試代碼。它使用map參數調用服務的activate方法。
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
}
}
一些代碼,我想測試有這樣一個服務的依賴:
public interface Service {
public void activate(Map<String, ?> params);
}
我想通過與嘲諷說的Mockito激活服務和驗證,以測試該代碼被稱爲一個合理的地圖。下面的代碼工作:
@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);
}
但是,我想測試,該地圖包含一個特定的條目。該Hamcrest hasEntry matcher似乎爲這個完美的使用案例:
@Test
public void testHasEntry() {
Service mockService = mock(Service.class);
Foo foo = new Foo(mockService);
foo.bar();
verify(mockService).activate(argThat(hasEntry("paramName", "paramValue")));
}
當我嘗試這一點,我得到的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
這裏的問題是,我需要的Map<String, ?>
一個的Mockito匹配,但hasEntry給了我一個Map<? extends String, ? extends String>
的匹配器。即使有明確的類型參數,我也無法弄清楚如何協調類型參數的「擴展」部分。我該怎麼做才能解決這個錯誤?是否有我應該使用的特定的強制類型或顯式類型參數?
據我所知,我可以使用ArgumentCaptor。這真的是唯一的方法嗎? Hamcrest匹配器可以嗎?
首先,我有錯誤的代碼片斷了。抱歉!現在更正。其次,這是行不通的。 Service.activate預計'Map',但在演員中不允許使用通配符。用'Object'替換'?'也不起作用。 –
Wesley
你能分享包括進口的測試代碼嗎? – VinPro
我已經在示例項目中添加了一個指向該問題的鏈接。 – Wesley