Tom*_*son 15 java outputstream mocking stream
'输出蒸汽'是指任何接收字节序列或字符或其他内容的对象.所以,java.io.OutputStream,还有java.io.Writer,javax.xml.stream.XMLStreamWriter的writeCharacters方法等等.
我正在为一个类编写基于模拟的测试,该类的主要功能是将数据流写入其中一个(XMLStreamWriter,就像它一样).
问题是数据流是在对write方法的一系列调用中编写的,但重要的不是调用,而是数据.例如,给定XMLStreamWriter out,这些:
out.writeCharacters("Hello, ");
out.writeCharacters("world!");
Run Code Online (Sandbox Code Playgroud)
相当于:
out.writeCharacters("Hello, world!");
Run Code Online (Sandbox Code Playgroud)
这对我的目的来说无关紧要.将会有一些特定的调用序列,但我不在乎它是什么,因此我不想写出对该特定序列的期望.我只是希望能够以任何方式写入某个特定的数据流.
一种选择是切换到基于状态的测试.我可以在缓冲区中累积数据,并对其进行断言.但是因为我正在编写XML,这意味着要做一些相当复杂和丑陋的断言.模拟似乎是处理编写XML的更大问题的更好方法.
那么我如何用模拟做到这一点?
我正在使用Moxie进行模拟,但我很想知道任何模拟库的方法.
Mr.*_*art 17
测试输出或输入流的一种相当优雅的策略是使用PipedInputStream和PipedOutputStream类.您可以在测试设置中将它们连接在一起,然后检查执行目标方法后写入的内容.
您可以在另一个方向上准备一些输入,然后让测试从输入流中读取这些准备好的数据.
在您的情况下,您可以使用PipedOutputStream 模拟该"out"变量,并以这种方式将PipedInputStream插入其中:
private BufferedReader reader;
@Before
public void init() throws IOException {
PipedInputStream pipeInput = new PipedInputStream();
reader = new BufferedReader(
new InputStreamReader(pipeInput));
BufferedOutputStream out = new BufferedOutputStream(
new PipedOutputStream(pipeInput))));
//Here you will have to mock the output somehow inside your
//target object.
targetObject.setOutputStream (out);
}
@Test
public test() {
//Invoke the target method
targetObject.targetMethod();
//Check that the correct data has been written correctly in
//the output stream reading it from the plugged input stream
Assert.assertEquals("something you expects", reader.readLine());
}
Run Code Online (Sandbox Code Playgroud)
我承认我可能偏向使用ByteArrayOutputStream作为最低级别的 OutputStream,在执行后获取数据并执行所需的任何断言。(也许使用 SAX 或其他 XML 解析器读取数据并深入研究结构)
如果你想用模拟来做到这一点,我承认我有点偏向Mockito ,并且我认为你可以使用自定义答案来完成你想要做的事情,当用户在你的模拟上调用 writeCharacters 时,将只需将它们的参数附加到 Buffer 中,然后您就可以对其进行断言。
这是我脑子里的想法(手写的,尚未执行,因此语法问题是可以预料的:))
public void myTest() {
final XMLStreamWriter mockWriter = Mockito.mock(XMLStreamWriter.class);
final StringBuffer buffer = new StringBuffer();
Mockito.when(mockWriter.writeCharacters(Matchers.anyString())).thenAnswer(
new Answer<Void>() {
Void answer(InvocationOnMock invocation) {
buffer.append((String)invocation.getArguments()[0]);
return null;
}
});
//... Inject the mock and do your test ...
Assert.assertEquals("Hello, world!",buffer.toString());
}
Run Code Online (Sandbox Code Playgroud)