我想测试两项服务:
首先,我正在构建一些复杂的文件结构(例如{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,这将创建一个文件(即我无法测试第一个服务)
在第二种情况下,我需要传递文件。如果我需要测试将写入指定文件的数据,我在第二次服务测试中该怎么办? (我无法测试第二次服务)
在第三种情况下,我认为我需要一些通用IO对象来包装File。 也许为此目的有一些现成的解决方案?
答案 0 :(得分:5)
在第一种情况下,如果您正在测试文件名生成,为什么还要关心文件本身?您不想测试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
}