简体   繁体   中英

Cannot verify the written value in a mocked output stream

I have the following method in my TcpTransport class:

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);
    }
}

And a test for it:

// 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();

The instance of outputStream was created like this:

outputStream = mock(OutputStream.class);

I'm using the same method for transform the string (which is the same instance, since the mocked envelopeSerializer class returns it) into a UTF-8 byte array. But I'm getting the following error:

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
);

Seems like the verify method for the mocked outputStream instance is checking the value of the parameter against an internal buffer, with the length of 8192 items. The generated class for the mocked OutputStream is OutputStream$$EnhancerByMockitoWithCGLIB$$b1c65902 .

Any ideas how can I verify if the write method has been called with the correct value with Mockito?

Instead of mocking the OutputStream, it is simpler to provide one. especially for text.

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

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

If you want to check for a flush() you could do

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM