IO测试
执行IO的组件在进行单元测试时可能会有些棘手。在本文中,我将对如何测试此类提供一些建议。
IO组件测试起来有些棘手的原因是,它们通常是从InputStream读取或者写入OutputStream或者类似的组件。为了测试这样的组件,我们需要能够控制从InputStream读取的数据,并能够访问写入OutputStream的数据。
测试输入组件
首先,让我们看一下一个从InputStream读取数据的组件。每当遇到逗号(,)时,该组件就会解析读取的数据,并将其分解为" String"令牌。它不是一个非常复杂的解析器,但是对于这个示例来说已经足够了。
public class MyIOUnit {
protected List<String> tokens = new ArrayList<String>();
public void read(InputStream input) throws IOException {
StringBuilder builder = new StringBuilder();
int data = input.read();
while(data != -1){
if(((char)data) != ','){
builder.append((char) data);
} else {
this.tokens.add(builder.toString().trim());
builder.delete(0, builder.length());
}
data = input.read();
}
}
}
注意read()方法如何将InputStream作为参数。让我们看一下如何为此类编写单元测试。
import org.junit.Test;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
public class MyIOUnitTest {
@Test
public void testRead() throws IOException {
MyIOUnit unit = new MyIOUnit();
byte[] data = "123,456,789,123,456,789".getBytes();
InputStream input = new ByteArrayInputStream(data);
unit.read(input);
assertEquals("123", unit.tokens.get(0));
assertEquals("456", unit.tokens.get(1));
assertEquals("789", unit.tokens.get(2));
assertEquals("123", unit.tokens.get(3));
assertEquals("456", unit.tokens.get(4));
assertEquals("789", unit.tokens.get(5));
}
}
注意如何从"字符串"创建字节数组,然后将其插入到" ByteArrayInputStream"实例中。然后,将ByteArrayInputStream用作MyIOUnitTest.read()方法的输入。这样,可以在单元测试期间控制单元的输入。
测试输出组件
也可以使用类似的方法测试写入" OutputStream"的组件。我们需要做的是使用一个OutputStream来收集其中的书面数据。 ByteArrayOutputStream类可以做到这一点。
这是一个写入OutputStream的单元(类):
public class MyIOUnit {
protected List<String> tokens = new ArrayList<String>();
public void write(OutputStream output) throws IOException {
for(int i=0; i<tokens.size(); i++){
if(i>0){
output.write(',');
}
output.write(tokens.get(i).getBytes());
}
}
}
这是单元测试,它使用ByteArrayOutputStream来收集写入传递到MyIOUnit.write()方法的OutputStream的数据:
import org.junit.Test;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
public class MyIOUnitTest {
@Test
public void testWrite() throws IOException {
MyIOUnit unit = new MyIOUnit();
ByteArrayOutputStream output = new ByteArrayOutputStream();
unit.tokens.add("one");
unit.tokens.add("two");
unit.tokens.add("three");
unit.write(output);
String string = new String(output.toByteArray());
assertEquals("one,two,three", string);
}
}
注意如何调用output.toByteArray()方法,并将其传递到String中。之后,将创建的"字符串"与预期的字符串"one,two,three"进行比较。
Reader和Writer
如果输入或者输出组件使用的是Reader或者Writer而不是InputStream或者OutputStream,则可以使用CharArrayReader和CharArrayWriter类来代替ByteArrayInputStream和ByteArrayOutputStream。
我们也可以在单元测试中使用StringReader和StringWriter类。

