测试文件生成方法

Korea Data Forum Fosters Collaboration and Growth
Post Reply
samiul51
Posts: 65
Joined: Wed Dec 11, 2024 10:18 am

测试文件生成方法

Post by samiul51 »

我们应该如何测试将其输出写入文件的类?
我们应该将这些文件存储在哪里才能使它们在任何操作系统上运行?
我们如何确定该文件不存在?
处理文件时,如果我们尝试自己解决这些问题,编写测试可能会很困难,如下例所示。下面的测试是一个质量可疑的旧测试。它应该测试是否DogToCsvWriter序列化并将狗写入 CSV 文件:

类 DogToCsvWriterShould {

私有DogToCsvWriter writer = new DogToCsvWriter("/tmp/dogs.csv");

@测试
void convertToCsv() {
writer.appendAsCsv(新狗(品种.CORGI,颜色.BROWN,“Monty”));
writer.appendAsCsv(新狗(品种.MALTESE,颜色.WHITE,“Zoe”));

字符串 csv = Files.readString("/tmp/dogs.csv");

assertThat(csv).isEqualTo("Monty,corgi,brownnZoe,maltese,white");
}
}
序列化过程应该与写入过程分离,但让我们专注于修复测试。

上述测试的第一个问题是它在 Windows 上无法运行,因为 Windows 用户无法解析路径/tmp/dogs.csv。另一个问题是,如果文件已经存在,它将无法运行,因为上述测试执行时不会删除该文件。它可能在 CI/CD 管道中正常工作,但如果多次运行,则无法在本地运行。

JUnit 5 有一个注释,您可以使用它来获取对框架为您创建和删除的临时目录的引用。虽然创建和删除临时文件的机制因框架而异,但思路是一样的。

类 DogToCsvWriterShould {

@测试
void convertToCsv(@TempDir Path tempDir) {
路径dogsCsv = tempDir.resolve("dogs.csv");
DogToCsvWriter 作者 = 新的 DogToCsvWriter(dogsCsv);
writer.appendAsCsv(新狗(品种.CORGI,颜色.BROWN,“Monty”));
writer.appendAsCsv(新狗(品种.MALTESE,颜色.WHITE,“Zoe”));

字符串 csv = Files.readString(dogsCsv);

assertThat(csv).isEqualTo("Monty,corgi,brownnZoe,maltese,white");
}
}
通过这一小改动,我们现在可以确保上述 罗马尼亚电话号码库 测试可以在 Windows、macOS 和 Linux 上运行,而无需担心绝对路径。它还将在测试后删除创建的文件,因此我们现在可以多次运行它,并且每次都能获得可预测的结果。

Image

命令与查询测试
命令和查询之间有什么区别?

命令:我们指示一个对象执行一个产生效果但不返回值的操作(void 方法)
查询:我们要求对象执行操作并返回结果或异常
到目前为止,我们主要测试了调用方法的查询,这些方法在执行阶段返回值或引发了异常。我们如何测试void方法并查看它们是否与其他类正确交互?框架提供了一组不同的方法来编写这些类型的测试。

到目前为止,我们为查询编写的断言都是以 开头的assertThat。在编写命令测试时,我们使用一组不同的方法,因为我们不再像查询那样检查方法的直接结果。我们希望“验证”我们的方法与系统其他部分的交互。

@ExtendWith(MockitoExtension.class)
类 FeedMentionServiceShould {

@嘲笑
私人 FeedRepository 存储库;

@嘲笑
私人 FeedMentionEventEmitter 发射器;

私人FeedMentionService服务;

@BeforeEach
无效设置(){
服务=新的FeedMentionService(存储库,发射器);
}

@测试
无效插入提及到Feed(){
长 feedId = 1L;
提及 mention = ...;

何时(repository.upsertMention(feedId,提及))
.thenReturn(UpsertResult.success(feedId,提及));

FeedInsertionEvent 事件 = 新 FeedInsertionEvent(feedId,提及);
mentionService.insertMentionToFeed(事件);

验证(发射器)。mentionInsertedToFeed(feedId,提及);
验证无更多交互(发射器);
}
}
在这个测试中,我们首先模拟我们的存储库,UpsertResult.success当被要求在我们的提要中更新插入提及时,FeedRepositoryShould它会做出响应。我们并不关心在这里测试存储库。存储库方法应该在中进行测试。通过模拟这种行为,我们实际上并没有调用存储库方法。我们只是告诉它下次调用时如何响应。

然后我们告诉我们mentionService将此提及插入到我们的 feed 中。我们知道,只有成功将提及插入到 feed 中时,它才应该发出结果。通过使用该verify方法,我们可以确保该方法mentionInsertedToFeed使用我们的提及和 feed 调用,并且不会使用再次调用verifyNoMoreInteractions。
Post Reply