Easymock模拟输入流读取操作

时间:2014-02-27 06:39:20

标签: java unit-testing easymock

我想用easymock测试以下代码。我已经创建了模拟套接字和模拟输入流,但我无法模拟读取方法。任何人都可以帮助我

byte[] lenbuf = new byte[2];
sock.getInputStream().read(lenbuf);

我在单元测试中尝试跟随

InputStream mockInputStream = createMock(InputStream.class);
expect(mockInputStream.read(new byte[2])).andReturn(2);
replay(mockInputStream);

它给了我以下错误

  Unexpected method call InputStream.read([0, 0]):
  InputStream.read([0, 0]): expected: 1, actual: 0

由于

3 个答案:

答案 0 :(得分:8)

(旁白:请尝试(byte[]) EasyMock.anyObject()而不是new byte[2]作为要阅读的参数。)

模拟输入流是很多工作,并不值得做。有许多方法可以获得测试可以设置的假输入流,而无需使用模拟对象。试试这个:

String fakeInput = "This is the string that your fake input stream will return";
StringReader reader = new StringReader(fakeInput);
InputStream fakeStream = new ReaderInputStream(reader);

请注意,ReaderInputStream位于Apache Commons IO

您也可以使用StringBufferInputStream在没有Reader的情况下执行此操作。这不需要Commons IO。它有缺陷,但它可能足以用于测试代码。

事实上,与其他形式的伪造相比,一般来说,嘲弄是一项艰苦的工作。我只是在我想要证明被测试的类的内部是以特定方式执行某些操作时才这样做,并且这不是真正的测试用途:良好的测试证明接口有效,并允许实现更改。阅读着名的Martin Fowler definition of mocks和Andrew Trenk对some of the problems they can introduce的看法。

答案 1 :(得分:0)

使用EasyMock#expect时,必须在目标类和单元测试中使用相同的对象。 在目标类的new byte[2]和单元测试的new byte[2]中是不同的对象。 您可能希望通过参数或接口传递对象。

示例:

// Unit test
@Test
public targetMethodTest() {
    InputStream mockInputStream = createMock(InputStream.class);
    byte[] lenbuf = new byte[2];
    expect(mockInputStream.read(lenbuf)).andReturn(2);
    replay(mockInputStream);
    ...
    targetClass.targetMethod(lenbuf);
}

...

// target method in target class
public void targetMethod(byte[] lenbuf) {
    ...
    sock.getInputStream().read(lenbuf);
}

如果您不关心lenbuf的价值,可以使用anyObject()代替new byte[2]

expect(mockInputStream.read(anyObject())).andReturn(2);

答案 2 :(得分:0)

尝试一下:

InputStream mockInputStream = IOUtils.toInputStream("fake string", StandardCharsets.UTF_8);