无法验证模拟输出流中的写入值

时间:2015-02-04 18:48:21

标签: java junit mockito

我的 TcpTransport 类中有以下方法:

public synchronized void send(Envelope envelope) throws IOException {
    ensureSocketOpen();
    String envelopeString = envelopeSerializer.serialize(envelope);

    if (traceWriter != null &&
            traceWriter.isEnabled()) {
        traceWriter.trace(envelopeString, TraceWriter.DataOperation.SEND);
    }

    try {
        byte[] envelopeBytes = envelopeString.getBytes("UTF-8");
        outputStream.write(envelopeBytes);
        outputStream.flush();
    } catch (UnsupportedEncodingException e) {
        throw new IllegalArgumentException("Could not convert the serialized envelope to a UTF-8 byte array", e);
    }
}

并测试它:

// Arrange
TcpTransport target = getAndOpenTarget(); // gets a valid instance
Envelope envelope = mock(Envelope.class);
String serializedEnvelope = DataUtil.createRandomString(200);
when(envelopeSerializer.serialize(envelope)).thenReturn(serializedEnvelope);

// Act
target.send(envelope);

// Assert
verify(outputStream, times(1)).write(AdditionalMatchers.aryEq(serializedEnvelope.getBytes("UTF-8")));
verify(outputStream, atLeastOnce()).flush();

outputStream的实例是这样创建的:

outputStream = mock(OutputStream.class);

我使用相同的方法将字符串(这是相同的实例,因为模拟的 envelopeSerializer 类返回它)转换为UTF-8字节数组。但我收到以下错误:

Argument(s) are different! Wanted:
outputStream.write(
    [102, 100, 104, 54, 111, 104, 55, 99, 51, 101, 120, 119, 99, 114, 50,     120, 104, 98, 98, 51, 99, 48, 120, 106, 55, 114, 102, 114, 102, 103, 50, 111, 108, 122, 109, 119, 117, 100, 50, 102, 114, 112, 51, 109, 114, 121, 49, 114, 104, 104, 103, 101, 104, 112, 54, 48, 54, 122, 98, 101, 113, 100, 54, 116, 51, 102, 106, 56, 118, 99, 102, 52, 98, 98, 105, 114, 111, 112, 111, 52, 102, 56, 97, 107, 51, 98, 107, 105, 119, 49, 117, 97, 98, 99, 48, 55, 53, 121, 102, 101, 50, 105, 117, 110, 115, 112, 112, 102, 53, 100, 54, 120, 117, 115, 117, 105, 99, 105, 109, 111, 100, 111, 122, 101, 57, 116, 102, 110, 55, 114, 52, 97, 114, 55, 48, 49, 113, 51, 97, 116, 57, 115, 110, 112, 55, 52, 106, 111, 101, 121, 112, 54, 100, 112, 111, 56, 102, 52, 115, 51, 99, 98, 99, 98, 102, 118, 107, 57, 99, 48, 98, 114, 111, 111, 115, 111, 120, 119, 106, 101, 103, 102, 99, 116, 98, 98, 114, 109, 110, 116, 113, 97, 53, 120, 52, 113, 111, 114, 118, 110]
);
-> at     org.limeprotocol.network.tcp.TcpTransportTest.send_validArgumentsAndOpenStreamAndTraceEnabled_callsWriteAndTraces(TcpTransportTest.java:98)
Actual invocation has different arguments:
outputStream.write(
    [102, 100, 104, 54, 111, 104, 55, 99, 51, 101, 120, 119, 99, 114, 50, 120, 104, 98, 98, 51, 99, 48, 120, 106, 55, 114, 102, 114, 102, 103, 50, 111, 108, 122, 109, 119, 117, 100, 50, 102, 114, 112, 51, 109, 114, 121, 49, 114, 104, 104, 103, 101, 104, 112, 54, 48, 54, 122, 98, 101, 113, 100, 54, 116, 51, 102, 106, 56, 118, 99, 102, 52, 98, 98, 105, 114, 111, 112, 111, 52, 102, 56, 97, 107, 51, 98, 107, 105, 119, 49, 117, 97, 98, 99, 48, 55, 53, 121, 102, 101, 50, 105, 117, 110, 115, 112, 112, 102, 53, 100, 54, 120, 117, 115, 117, 105, 99, 105, 109, 111, 100, 111, 122, 101, 57, 116, 102, 110, 55, 114, 52, 97, 114, 55, 48, 49, 113, 51, 97, 116, 57, 115, 110, 112, 55, 52, 106, 111, 101, 121, 112, 54, 100, 112, 111, 56, 102, 52, 115, 51, 99, 98, 99, 98, 102, 118, 107, 57, 99, 48, 98, 114, 111, 111, 115, 111, 120, 119, 106, 101, 103, 102, 99, 116, 98, 98, 114, 109, 110, 116, 113, 97, 53, 120, 52, 113, 111, 114, 118, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  
(+ a lot of zeros)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
0,
200
);

似乎模拟的 outputStream 实例的验证方法是针对内部缓冲区检查参数的值,长度为8192项。生成的模拟OutputStream的类是 OutputStream $$ EnhancerByMockitoWithCGLIB $$ b1c65902

任何想法如何验证是否已使用Mockito使用正确的值调用write方法?

1 个答案:

答案 0 :(得分:5)

不是模拟OutputStream,而是提供一个更简单。特别是对于文本。

outputStream = new ByteArrayOutputStream();
outputStream.write("Hello World".getBytes());

assertEquals("Hello World", outputStream.toString());

如果你想检查冲洗(),你可以做

boolean[] flushed = { false };
outputStream = new ByteArrayOutputStream() {
    public void flush() throws IOException {
        super.flush();
        flushed[0] = true;
    }
};