我在我的测试类中调用了以下方法:
class ClassUnderTest {
[...]
restTemplate.getForEntity(url, MyResponseEntity.class, parameterMap);
[...]
}
在包含此行的类的单元测试中,我想存根getForEntity
方法,以便它为parameterMap
中的不同条目返回不同的响应。
使用BDDMockito,我试图通过使用argThat
来匹配所需参数是parameterMap的一部分:
@InjectMocks
private ClassUnderTest classUnderTest;
@Mock
private RestTemplate restTemplate;
[...]
given(restTemplate.getForEntity(anyString(), any(Class.class), argThat(hasEntry("myKey", "myValue"))
.willReturn(responseEntityA);
但是,如果我运行测试使parameterMap
包含(我在调试器中验证了这一点)一个键“myKey”和一个值“myValue”,我得到一个NullPointerException
,因为mockito似乎无法将方法调用与我创建的存根匹配。
另一方面,使用以下非常通用的匹配允许我在没有NPE的情况下运行我的测试,为所有调用提供默认响应,但它不允许我定义自定义响应给定的参数。
given(restTemplate.getForEntity(anyString(), any(Class.class), anyMap())
.willReturn(defaultResponseEntity);
这是什么原因? argThat
仅适用于具有单个参数的方法吗?
还有另一种方法可以将getEntity
的调用与包含特定(键,值)对的地图进行匹配吗?
答案 0 :(得分:3)
argThat
肯定适用于多个参数,并且您尝试做的事情没有明显错误。我有一种唠叨的预感,它正在选择the wrong overload:
getForEntity(String url, Class<T> responseType, Map<String,?> urlVariables)
getForEntity(String url, Class<T> responseType, Object... urlVariables)
如果泛型不完全匹配,Java可能会认为您的hasEntry
最匹配Object...
与anyMap
匹配的Map<String, ?>
方法。在这种情况下,您将存在未调用的重载(Object...
),并且Mockito将恢复为您在被测系统中实际调用的默认返回值(Map<String, ?>
)。将鼠标悬停在IDE中的方法调用上可以了解编译器匹配的过载。
为了给Java提供更好的提示,请尝试使用强制转换,如下所示(警告,未经过测试或验证):
given(restTemplate.getForEntity(
anyString(),
any(Class.class),
(Map<String, ?>) argThat(hasEntry("myKey", "myValue"))))
.willReturn(responseEntityA);
答案 1 :(得分:0)
我不确定为什么argThat
不适合您,但您可以尝试使用thenAnswer
并检查Answer
中的参数。