java capture,java – Mockito Capture在捕获时不维护捕获的列表

在Mockito中,我们遇到的情况是列表的捕获不会返回预期的结果.测试用例:

>我们将“Pip”添加到列表中

>我们捕获列表

>我们在列表中添加“Sok”.

在我们的断言中,我们只期望“Pip”在那里,但“Sok”也在那里.我们认为这是不正确的,因为在捕获时“Sok”不在列表中.

java.lang.AssertionError:

预计:[Pip]

实际:[Pip,Sok]

>有人有解决方案吗?

>这是Mockito中的错误还是功能?

>为什么Mockito保留对列表的引用而不复制

列表一个捕获时间?

以下是测试用例:

@RunWith(MockitoJUnitRunner.class)

public class CaptureTest {

@Captor

private ArgumentCaptor listCapture;

@Mock

private ListPrinter listPrinter;

private TestClass testClass;

@Before

public void setUp() {

testClass = new TestClass(listPrinter);

}

@Test

public void testCapture() {

testClass.simulateFailSituation();

verify(listPrinter).printList(listCapture.capture());

// THIS FAILS: Expected:[Pip], Actual:[Pip, Sok]

assertEquals(Collections.singletonList("Pip"), listCapture.getValue());

}

public class TestClass {

private List list = new ArrayList();

private ListPrinter listPrinter;

public TestClass(ListPrinter listPrinter) {

this.listPrinter = listPrinter;

}

private void simulateFailSituation() {

list.add("Pip");

listPrinter.printList(list);

list.add("Sok");

}

}

public interface ListPrinter {

void printList(List list);

}

}

解决方法:

这可能听起来像一个惊人的功能,但然后想一想:如果它正在复制,它应该停在哪里?您可能会捕获一些对其他对象有很多引用的对象,并且最终可能会对JVM实例中的几乎所有对象进行深层复制.

这将是一个严重的性能打击,所以我有点理解为什么.

因此,您可以选择两种方法:

>在适用的地方使用不可变对象.除了更容易测试之外,它还使代码更易于阅读和调试.

>在通话时立即测试值,而不是捕获参考值.对于void方法,您可以使用带有Answer< Void>的doAnswer方法,在那里进行测试或复制.顺便说一下,这是新的,见How to make mock to void methods with mockito.

我发现它比验证更强大.在您的情况下,doAnswer看起来像这样:

doAnswer(invocation -> {

assertEquals(Collections.singletonList("Pip"), invocation.getArguments()[0]);

return null;

}).when(listPrinter).printList(Matchers.anyList());

标签:java,unit-testing,mockito,capture

来源: https://codeday.me/bug/20190710/1426726.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值