2014-02-27 60 views
3

我想用easymock测试下面的代码。我创建了模拟套接字和模拟输入流,但我无法模拟读取方法。任何人都可以请帮我Easymock嘲笑inputstream读操作

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 

感谢

+0

使用匹配器。无论是EasyMock.aryEq()或EasyMock.capture(),取决于你想要测试它。 –

回答

7

(旁白:尽量(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。这不需要Commons IO。它有缺陷,但对于测试代码来说可能足够好。

事实上,与其他形式的伪造相比,嘲笑总的来说是艰苦的工作。我只是在我想证明被测试的类的内部是以某种特定方式做某件事情时才这样做,而这实际上并不是测试的目的:好的测试证明了这些接口的工作,并允许实现发生改变。阅读着名的Martin Fowler的definition of mocks和Andrew Trenk的some of the problems they can introduce

+0

+1为您的存根建议。接下来,它使我的测试简单:)谢谢 – amique

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