如何在JUnit中测试IO代码?

| 我要测试两项服务: 建立文件名的服务 将一些数据写入第一个服务提供的文件中的服务 首先,我要构建一些复杂的文件结构(例如
{user}/{date}/{time}/{generatedId}.bin
) 在第二个中,我将数据写入第一个服务传递的文件(第一个服务调用第二个服务) 如何在不进行任何实际IO干扰的情况下使用模拟测试这两种服务? 例如: 一号服务:
public class DefaultLogService implements LogService
{

    public void log(SomeComplexData data)
    {
        serializer.write(new FileOutputStream(buildComplexFileStructure()), data);
        or
        serializer.write(buildComplexFileStructure(), data);
        or
        serializer.write(new GenericInputEntity(buildComplexFileStructure()), data);
    }

    private ComplextDataSerializer serializer; // mocked in tests
}
第二次服务:
public class DefaultComplexDataSerializer implements ComplexDataSerializer
{

    void write(InputStream stream, SomeComplexData data) {...}
    or
    void write(File file, SomeCompexData data) {...}
    or
    void write(GenericInputEntity entity, SomeComplexData data) {...}

}
在第一种情况下,我需要传递FileOutputStream来创建一个文件(即我无法测试第一项服务) 在第二种情况下,我需要传递文件。如果我需要测试将写入指定文件的数据,该如何在第二服务测试中做什么? (我无法测试第二项服务) 在第三种情况下,我认为我需要一些将包装File的通用IO对象。 也许为此目的有一些现成的解决方案?     
已邀请:
        在第一种情况下,如果要测试文件名生成,为什么还要关心文件本身?您不想测试FileOutputStream。 我假设您的方法如下所示:
public File buildComplexFileStructure() {
    // code
}
您的测试将如下所示:
@Test public void test() throws Exception {
    File expected = <what you expect to be generated>;
    File actual = new DefaultLogService().buildComplexFileStructure();
    assertEquals(expected, actual);
}
如果该方法未公开公开,则将其公开进行测试(默认或受保护)。 在第二种情况下,您不能将ByteArrayOutputStream从测试测试传递到您的方法中,然后验证所写入的内容吗?即:
@Test public void test() throws Exception {
    btye[] expected = <expected data>;
    ByteArrayOutputStream actualStream = new ByteArrayOutputStream();
    new DefaultComplexDataSerializer().write(actualStream, data);
    byte[] actualData = actualStream.toByteArray();
    // compare expected and actualData
}
    

要回复问题请先登录注册