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
类。