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