Java 如何使用Mockito验证带有ByteBuffer参数的调用?
我正在尝试为使用Java 如何使用Mockito验证带有ByteBuffer参数的调用?,java,junit,mockito,bytebuffer,Java,Junit,Mockito,Bytebuffer,我正在尝试为使用ByteBuffer的库创建一个测试 简化版本如下: public class ByteBufferTest { public static class Stuff { public void doSomething(Target target, ByteBuffer buffer) { ByteBuffer slice = buffer.slice(); slice.limit(1);
ByteBuffer
的库创建一个测试
简化版本如下:
public class ByteBufferTest {
public static class Stuff {
public void doSomething(Target target, ByteBuffer buffer) {
ByteBuffer slice = buffer.slice();
slice.limit(1);
target.accept(slice);
target.command();
buffer.position(1);
target.accept(buffer);
// do more with the buffer
buffer.get();
}
}
private interface Target {
void accept(ByteBuffer slice);
void command();
}
@Test
public void doSomething() {
final Stuff stuff = new Stuff();
final Target mockTarget = Mockito.mock(Target.class);
stuff.doSomething(mockTarget, ByteBuffer.wrap(new byte[]{1, 2, 3, 4}));
InOrder inOrder = Mockito.inOrder(mockTarget);
inOrder.verify(mockTarget).accept(ByteBuffer.wrap(new byte[]{1}));
inOrder.verify(mockTarget).command();
inOrder.verify(mockTarget).accept(ByteBuffer.wrap(new byte[]{2, 3, 4}));
}
}
如果doSomething
方法没有缓冲区.get()代码>在末尾
此测试失败,因为在inOrder.verify(mockTarget.accept)(ByteBuffer.wrap(新字节[]{2,3,4}))调用了code>,传入的参数随后被buffer.get()
调用修改
是否有方法在调用时验证该缓冲区的内容?选项a。如果很难测试,可能实现也有问题?是否每个目标都应该立即作用于此缓冲区?也许我们只是在第二次调用时交另一个片段:
target.accept(buffer.slice());
选项B.不测试平台,只测试交互:
@测试
公共无效doSomething1(){
最终材料=新材料();
最终目标mockTarget=mock(Target.class);
final ByteBuffer buffer=mock(ByteBuffer.class);
最终ByteBuffer切片=模拟(ByteBuffer.class);
给定(buffer.slice())。将返回(slice);
剂量测定法(模拟靶、缓冲);
final inoorder inoorder=Mockito.inoorder(mockTarget);
inOrder.verify(mockTarget).accept(slice);
inOrder.verify(mockTarget.command();
inOrder.verify(mockTarget).accept(buffer);
}
选项C.您自己的ByteBuffer
的双重测试实现通常会给您完全的控制权,除非Buffer/ByteBuffer/HeapByteBuffer类层次结构不会像现在这样对测试不友好。这不意味着测试有效地失败了吗;如果doSomething
方法调用buffer.get()
,则生成的ByteBuffer将删除一个附加元素。在调用accept
时,它包含正确的数据。doSomething
的契约就是用数据的子集调用accept
方法,数据缓冲区,但是accept
返回后并不拥有缓冲区。真正的用例要复杂一些(它实际上解析了ByteBuffer
的内容,并将其分为3部分:预数据、命令和后期数据。然后它负责确保后期数据被使用。为什么目标是模拟的,而缓冲区不是?这似乎很奇怪。我处理缓冲区的主要原因不是模拟的,是ByteBuffer的是模拟的。)相当“原始”喜欢,除了它们是可变的。您可能不会模拟字符串实例,甚至不会模拟基本包装器。所以对我来说,不模拟缓冲区是可以的。感谢您周到的响应。这是性能关键代码,所以如果可能的话,我希望避免不必要的切片。总的来说,能够在调用时验证参数状态就像Mockito应该支持t。@Daniel我在回答中又增加了两个想法。您显示的代码片段不必要地与doSomething的实现细节相耦合。doSomething的合同是发送数据、发送命令、发送更多数据。它不(也不应该)指定该数据是切片、传入缓冲区还是构造函数bytebuffer。在任何情况下,我现在决定将代码更改为仅重用早期切片。好的。是的,最终,要断言的特定交互取决于您的需求。减少这些切片()调用听起来像是一种改进。