Java Mockito失败的原因是;论点不同;但调试器的表现不同
我正在测试一个方法,它使用Mockito模拟对象。当我运行测试时,Mockito告诉我传入参数的参数与预期的不同。如果我在测试的方法中设置了断点,那么调用它的参数实际上就是我所期望的。此方法只被调用一次。为什么Mockito报告的内容与我在调试器中看到的有所不同,我如何修复这个问题 以下是测试:Java Mockito失败的原因是;论点不同;但调试器的表现不同,java,mockito,Java,Mockito,我正在测试一个方法,它使用Mockito模拟对象。当我运行测试时,Mockito告诉我传入参数的参数与预期的不同。如果我在测试的方法中设置了断点,那么调用它的参数实际上就是我所期望的。此方法只被调用一次。为什么Mockito报告的内容与我在调试器中看到的有所不同,我如何修复这个问题 以下是测试: @Test public void addExclusivePermutationsTest() { Permutation p1 = mock(Permutation.class);
@Test
public void addExclusivePermutationsTest() {
Permutation p1 = mock(Permutation.class);
PermutationBuilder pb = new PermutationBuilder();
when(p1.applyPermutations(anySetOf(String.class)))
.thenReturn(Collections.singleton("abc123"));
pb.addExclusivePermutations(p1);
pb.permute("test");
verify(p1).applyPermutations(new HashSet<>(
Collections.singletonList("test")));
}
上述方法在permute(“test”)
内部调用。字符串“test”
被转换为集合
,并传递到上述方法中。上面的方法在p1
上调用applyPermutations
。当我使用调试器查看此方法时,stringPermutations
只包含[test]
,正如我所期望的那样,并直接传递到p1
。然后p1
返回[abc123]
,因为它是模拟的,上面的方法将它与stringPermutations
结合起来,以返回[test,abc123]
。因此出于某种原因,Mockito说stringPermutations
不是调试器显示的[test]
,而是方法返回的结果
最后,这里是错误:
Argument(s) are different! Wanted:
permutation.applyPermutations(
[test]
);
-> at PermutationBuilderTest$AddExclusivePermutationTests.addExclusivePermutationsTest(PermutationBuilderTest.java:87)
Actual invocation has different arguments:
permutation.applyPermutations(
[abc123, test]
);
最后一个提示(对于仍在阅读的读者)。如果我通过复制ExclusivePermutation.applyPermutation()
并将其直接放入PermutationBuilder
中来绕过ExclusivePermutation
,则测试通过。这是一个谜
编辑:
所以我把范围缩小了一点。在PermutationBuilder
中,我有以下方法:
public Set<String> permute(String s) {
for (Modifier modifier : modifierList) {
s = modifier.applyModification(s);
}
Set<String> stringPermutations = new HashSet<>(Collections.singletonList(s));
for (Permutation permutation : permutationList) {
Set<String> result = permutation.applyPermutations(stringPermutations);
stringPermutations.addAll(result);
}
return stringPermutations;
}
公共集置换(字符串s){
用于(修改器:修改器列表){
s=修饰符。应用修改;
}
Set stringPermutations=新哈希集(Collections.singletonList);
for(置换置换:置换列表){
集合结果=置换。applyPermutations(stringPermutations);
stringPermutations.addAll(结果);
}
返回字符串置换;
}
分配完结果后,Mockito说该方法是通过[test]
调用的。但是,当我跳到下一行将其添加到stringPermutations
时,它将更改为[abc123,test]
。您可以在下面的两个屏幕截图中看到这一点(查看参数
数组底部):
问题在于您正在修改用作参数的集合 也就是说,在代码中
Set<String> stringPermutations = new HashSet<>(Collections.singletonList(s));
for (Permutation permutation : permutationList) {
Set<String> result = permutation.applyPermutations(stringPermutations);
stringPermutations.addAll(result);
}
如果您确实需要
stringPermutations
来包含这两个元素。mockito github中针对同一问题有两个问题:
- org.mockito.internal.stubing.answers.ClonesArguments
- 在doAnswer中进行手动复制,并代替captor进行验证
doAnswer((invocation) -> {
new ClonesArguments().answer(invocation);
// in my case situation is different and instead of modifying invocation
// my argument is the same collection 4 times with different elements
// in your case it may or may not work
// maybe you will have to copy paste and update their code
return myAnswer;
})
我在debug中看到我的集合的元素被复制,但在验证阶段我仍然只看到最新的值,因此对我来说不起作用。您是否尝试了
verify(p1).applyPermutations(Mockito.eq(新的HashSet(Collections.singletonList(“test”))代码>?@RahulSharma我已经试过了,但正如我所预料的那样,它没有帮助。问题不是这些集合包含相同的元素,而是它们的计算结果不相等。问题是Mockito说这些集合包含不同的元素,但调试器却不这么说,我需要弄清楚为什么会发生这种情况。你说得对!太棒了,我完全被难住了。谢谢虽然这是正确的,并解释了发生了什么,但为相同的单元测试和模拟更改生产代码没有多大意义。是否有任何解决方案可以通过复制传入对象来捕获?
Set<String> stringPermutations = new HashSet<>();
for (Permutation permutation : permutationList) {
Set<String> result = permutation.applyPermutations(Collections.singletonList(s));
stringPermutations.addAll(result);
}
stringPermutations.addAll(Collections.singletonList(s));
doAnswer((invocation) -> {
new ClonesArguments().answer(invocation);
// in my case situation is different and instead of modifying invocation
// my argument is the same collection 4 times with different elements
// in your case it may or may not work
// maybe you will have to copy paste and update their code
return myAnswer;
})