【发布时间】:2015-06-22 06:19:30
【问题描述】:
我发现为算法编写单元测试很容易。比如sort(List),很容易写出这样的测试:
list = [2, 1, 4];
assert(sort(list) == [1, 2, 4]);
但我发现很难测试没有逻辑的方法,没有if 语句,只有一组调用。
关于如何对它们进行单元测试,主要有 2 个示例:
示例 1:
假设我有一个类负责将一些数据写入文件,但这些数据是由外部函数(writeHeaderToFile、writeSerializedData 和 writeEndOfFile)以特定方式写入的。
数据不是直接写入文件的,所以如果数据是这样的:
{
list: [
"item 1",
"item 2"
],
name: "aaa"
}
这并不意味着该文件既不是该数据的纯文本版本(没有空格),也不是简单的序列化版本或文件中的加密版本。实际的文件二进制文件对我来说是未知的。我所知道的是,我可以使用这三种方法以正确的方式写作。
此文件还包含一些其他信息,这些信息并非直接来自这 3 种方法,例如特定类型的标头(同样,我不知道它将如何在文件二进制文件中表示)。
那是类:
class FileCreator {
populateFileWithData(File file, Data data) {
doBlockWithLock(file, {
Header header;
header.format = SomeFormat;
header.version = SomeVersion;
writeHeaderToFile(file, header);
writeSerializedData(file, data);
writeEndOfFile(file);
});
}
// Private
void doBlockWithLock(File file, Lambda block) {
file.holdWritingLock();
block();
file.releaseWritingLock();
}
}
示例 2:
class Controller {
var screenOne = new ScreenOne();
var screenTwo = new ScreenTwo();
var screenThree = new ScreenThree();
void reloadButtonWasClicked() {
screenOne.reload();
screenTwo.reload();
screenThree.reload();
}
}
对于这个我可以做这样的事情:
var mockScreenOne = Mock<ScreenOne>().reload.expectOneCall();
var mockScreenTwo = Mock<ScreenTwo>().reload.expectOneCall();
var mockScreenThree = Mock<ScreenThree>().reload.expectOneCall();
Controller controller = new Controller();
controller.screenOne = mockScreenOne;
controller.screenTwo = mockScreenTwo;
controller.screenThree = mockScreenThree;
controller.reloadButtonWasClicked();
mockScreenOne.verify();
mockScreenTwo.verify();
mockScreenThree.verify();
但我没有发现它有多大价值,因为我只是在断言我正在做与我在实现中所做的相同的事情。对我来说似乎是代码重复。
测试我的 2 个示例的正确方法是什么?
【问题讨论】:
-
暂且不说最后一个例子,在第一个例子中,你是说你不知道 writeSerializedData 或其他方法会做什么?你不知道会产生什么样的 fileFileCreator,也许是因为这些方法是另一个代码库或其他东西的一部分?
-
没错!我确实有一些想法,它是“我的”代码库,我只是没有时间来理解这一切,如果你明白我的意思的话......
-
如果我在测试它,我会简单地测试
FileCreator.populateFileWithData是否完成而不抛出异常。在我删除我的临时测试文件之前,我还会检查目标文件是否存在(因为它应该存在)。对于第二个,我将检查它对重新加载做出适当反应的每个屏幕;它是否填写了它应该没有错误的东西。 -
@RodrigoRuiz 在这种情况下可能更有价值的是集成测试而不是单元测试。具有序列化程序实现的 FileCreator 是否生成正确的文件?单击重新加载按钮是否会在视图中产生正确的行为?但是,由于类的简单性,它们可能未经测试。它们非常简单,要么工作要么不工作。只需使用该应用程序,您可能会注意到存在的错误。
-
@thalesmello 所以基本上你不会像我的控制器那样测试没有逻辑的类?
标签: unit-testing tdd