IO测试

时间:2020-01-09 10:35:39  来源:igfitidea点击:

执行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。

我们也可以在单元测试中使用StringReaderStringWriter类。