以递增方式执行此操作的最佳方法是什么? 例如。有些网址必须先访问其他网址以填充数据库等。是否有一个惯用的节点单元测试方式?
我目前从json文件中读取单元测试数据,然后根据该请求进行请求。
function urlTestFn(test){
var req = requestProperties(test);
var request = http.request(req, function(resp) {
resp.setEncoding('utf8');
resp.on('data',function(data) {
if(data == JSON.stringify(test.response)) {
//success
} else {
sys.puts('fail');
}
});
});
if(req.method == 'POST'){
request.write(JSON.stringify(test.postData));
}
request.end();
}
答案 0 :(得分:2)
为了补充Peter Lynos的建议,请允许我向您介绍单元测试的正确概念。在进行单元测试时,很多人都会提出错误的问题。这不是“我该如何测试”,而是“我要测试什么”。在您的情况下,您想要测试您的代码,逻辑,而不是其他任何东西。这意味着您必须删除所有外部因素,包括第三方库,npm模块,甚至node.js核心API模块。
问问自己 - 你可以复制你的测试套件并运行它而无需花费数小时来设置环境吗?你应该能够。这就是编写单元测试的全部要点 - 让它独立运行以确保您的代码正确无误。我们称之为“环境”,您的代码可以独立运行“控制环境”,类似于科学界使用的相同术语。
现在要实现这一点,你需要了解灯具和模拟的概念。夹具可以创建您的控制环境。它通过创建一组模拟对象来实现,其中每个模拟对象获取输入并生成输出。通过这种方式,您可以精确控制代码的各个方面,并且可以轻松地测试从数据库操作到REST请求的各种内容。
最后,明白了:
模拟对象
假设在你的函数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',它将返回'This is the files contents'。
依赖注入
如果您的项目没有被编写为从外部注入依赖项,那么上述所有内容将非常困难。现在我的约定是所有模块都必须有一个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才能在您的项目中充满乐趣。希望这有帮助!
答案 1 :(得分:1)
好的,一些提示。您的代码似乎没有使用任何测试框架,所以至少要使用commonJS断言或测试框架。我更喜欢jasmine,但有几个好的。 Jasmine对间谍和异步测试有很大的支持。作为旁注,这些不是单元测试,根据定义,它们不会访问数据库,这些很可能是应用程序/系统测试。除了通过整个堆栈发送实时数据的系统级测试之外,您可能还需要考虑为服务器端代码编写一些纯单元测试。
关于测试先决条件的主题,通常尝试使每个测试尽可能独立。但是当完全独立性无法避免时,大多数单元测试框架都有一个setup
/ teardown
函数对的概念,这些函数在每次测试之前和之后调用。在jasmine中,这是beforeEach
函数。将DB对象预加载为“fixture”有时在Rails社区中完成。还有“工厂”的概念。每种策略都有优点和缺点。我不确定是否有工厂或灯具的节点库,但是进行网络搜索。