当前位置: 首页 > 知识库问答 >
问题:

如何测试外部类执行的IO?

赵兴朝
2023-03-14

我有一个简单的类,它将数据写入CSV文件

public class CsvFileWriter {
    private static Logger logger = LogManager.getLogger();

    public static void writeDataToCsvFile(String filePath, List<String[]> data) {
        File file = new File(filePath);
        try (FileWriter outputFile = new FileWriter(file)) {
            CSVWriter writer = new CSVWriter(outputFile, ' ',
                    CSVWriter.NO_QUOTE_CHARACTER,
                    CSVWriter.DEFAULT_ESCAPE_CHARACTER,
                    CSVWriter.DEFAULT_LINE_END);
            writer.writeAll(data);
        } catch (IOException e) {
            logger.error("Unable to find the specified path", e);
            throw new ProjectException(e);
        }
    }
}

我想知道如何测试这个类中包含的方法。我发现信息表明这可以通过使用Mockito来实现。是这样吗?我该怎么做呢?

共有1个答案

洪高阳
2023-03-14

您不需要Mockito或任何模拟来测试它(故障处理和日志记录除外)。您应该使用Junit 5中的@TempDir或Junit 4中的TemporaryFolder

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

class CsvFileWriterTest {
    @Test
    void createsCsvFile(@TempDir final Path temp) {
        final var csv = temp.resolve("test.csv");
        CsvFileWriter.writeDataToCsvFile(
                csv.toString(),
                List.of(
                        new String[]{"1", "abc"},
                        new String[]{"2", "def"}
                )
        );
        Assertions.assertTrue(csv.toFile().exists());
    }

    @Test
    void writesDataToCsv(@TempDir final Path temp) throws IOException {
        final var csv = temp.resolve("test.csv");
        CsvFileWriter.writeDataToCsvFile(
                csv.toString(),
                List.of(
                        new String[]{"1", "abc"},
                        new String[]{"2", "def"}
                )
        );
        Assertions.assertEquals(
                Files.readAllLines(csv),
                List.of("1 abc", "2 def")
        );
    }
}

尽管您可能希望重构类以提高可测试性:

@lombok.RequiredArgsConstructor
public class CsvFileWriter {
    private static final Logger LOG = LogManager.getLogger();
    private final Path file;
    private final Function<Writer, CSVWriter> csvfactory;

    public CsvFileWriter(final Path file) {
        this(
            file,
            writer ->
                new CSVWriter(writer, ' ',
                    CSVWriter.NO_QUOTE_CHARACTER,
                    CSVWriter.DEFAULT_ESCAPE_CHARACTER,
                    CSVWriter.DEFAULT_LINE_END
                )
        );
    }

    public void write(final List<String[]> data) {
        try (var csv = this.csvfactory.apply(Files.newBufferedWriter(this.file))) {
            csv.writeAll(data);
        } catch (IOException ex) {
            LOG.error("Unable to find the specified path", ex);
            throw new UncheckedIOException(ex);
        }
    }
}

现在,您可以将工厂方法传递给构造函数,并使用它来模拟 CSVWriter。例如,您可以测试 IOException 是否由您的类进行相关处理:

@Test
void handlesIoException(@TempDir final Path temp) {
    final var mock = Mockito.mock(CSVWriter.class);
    Mockito.doThrow(IOException.class).when(mock).writeAll(Mockito.anyList());
    final var writer = new CsvFileWriter(temp.resolve("not.csv"), wrt -> mock);
    Assertions.assertThrows(
        UncheckedIOException.class,
        () -> writer.write(List.of())
    );
}
 类似资料:
  • 在一个SpringBoot应用程序中,我想做一些关于存储库层的测试。 当我尝试从运行测试时,我得到一个关于的错误 com.norc.application中得字段defaultConfigService需要类型为“com.norc.service.defaultConfigService”得bean,但找不到该bean. 那么这需要运行吗? 我尝试在中放入的bean,但这是不允许的。 那该怎么管理

  • 问题内容: 我是Swift的新手,我没有发现任何有关使用Swing语言执行外部程序或访问外部进程的信息。 在语言开发的当前阶段是否可以做,还是应该改用Objective-C? 也许我的Swift程序中可以使用一些Objective-C库? 谢谢。 问题答案: 您可以使用运行外部程序。例如,从Circle和Square:

  • 22.13.1.执行测试 测试从main构建过程中分离出来的,运行在一个单独的JVM中执行.Test任务允许控制这些如何发生. 有许多属性用于控制测试过程如何启动.这包括使用诸如系统属性,JVM参数和Java可执行文件。 可以指定是否要并行执行测试.Gradle通过同时运行多个测试进程提供并行执行测试.每个测试进程在同一时间只能执行一个测试,为了充分利用这一特性,一般不需要为tests任务做什么特

  • 我有maven surefire插件pom.xml: 现在我希望maven只在部署目标上执行测试,因此: 当执行mvn部署测试应该运行 当执行mvn包或mvn安装时,测试不应该运行,因为目标在部署之前

  • 我试图制作一个调用外部程序的应用程序,我必须传递两个参数。它没有给出任何错误。 ,用C编写,拍摄照片并修改