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})),传入的参数随后被
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。在任何情况下,我现在决定将代码更改为仅重用早期切片。好的。是的,最终,要断言的特定交互取决于您的需求。减少这些切片()调用听起来像是一种改进。