要增加Peter Lynos的建议,请允许我向您介绍单元测试的正确思路。在进行单元测试时,很多人会问错误的问题。这不是“我该如何测试”,而是“我要测试什么”。在你的情况下,你想测试你的代码,逻辑,而不是别的。这意味着您必须删除所有外部因素,包括第三方库,npm模块,甚至是node.js核心API模块。
问问你自己:你可以复制你的测试套件并运行它,而无需花费几个小时来设置环境?你应该能够。这就是编写单元测试的重点 - 使其单独运行以确保代码正确。我们称之为“环境”,您的代码可以独立于“控制环境”运行,类似于科学界使用的相同术语。
现在要实现这一点,您需要了解灯具和嘲笑的概念。有灯具可以创造你的控制环境。它通过创建一堆模拟对象来实现,其中每个模拟对象接受输入并生成输出。通过这种方式,您可以精确控制代码的各个方面,并且使测试从DB操作到REST请求的各种东西变得非常简单。
最后,在理解的是:
- 最好测试套件是一个可以在一个孤立的,控制环境
- 夹具被用来创建该环境通过提供您的代码与模拟对象
运行
- 模拟对象需要输入并返回输出
- 以上三件事情只有在您已经用100%注入依赖项编码项目时才能实现
mock对象
假设在你的函数foo()要读取文件的内容,这里是你的模拟看起来应该像:
var FsMock = {
readFile : function readFile(path, encoding, callback) {
if (path === 'unit-test-1')
callback(null, 'This is the file contents');
else
callback(new Error('Unexpected error');
}
}
,然后在测试代码,你尝试读取文件'unit-test-1',它将返回'这是文件内容'。
依赖注入
上述所有的是,如果你的项目没有写他们之间的依赖外部注入极其困难。现在我的约定是所有模块都必须有一个make()函数,它接受一个包含所有依赖关系的对象。这里有一个简单的例子:
var Fs = null;
var Path = null;
var TestObj = module.exports = {
make : function make(args) {
if ('undefined' === typeof args.fs)
throw new Error('Dependency: FS module needed');
if ('undefined' === typeof args.path)
throw new Error('Dependency: Path module needed');
Fs = args.fs;
Path = args.fs;
return Object.create(this);
}
}
然后你需要一个工厂或DI容器为你的对象构建它,自动构造它的依赖关系。
只有这样,BDD和TDD才会在您的项目中变得有趣。希望这可以帮助!