2011-05-12 109 views
0

渐进地做这件事的最好方法是什么?例如,一些网址必须在别人之前访问才能填充数据库等。是否有单元测试的惯用节点方式?Nodejs单元测试网址

我目前从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(); 
} 

回答

1

确定,一些提示。你的代码似乎没有使用任何测试框架,所以至少应该使用commonJS断言或测试框架。我更喜欢jasmine,但有几个好的。茉莉花对间谍和异步测试有很大的支持。作为一个方面的评论,这些不是单元测试,根据定义它不会触及数据库,这些测试最有可能是应用程序/系统测试。除了这些通过整个堆栈发送实时数据的系统级测试之外,您可能还想考虑为您的服务器端代码编写一些纯粹的单元测试。

关于测试先决条件的主题,通常尽量使每个测试尽可能独立。但是,当完全独立性不可避免时,大多数单元测试框架都有一个概念,即在每次测试之前和之后调用的一对函数。在jasmine中,这是beforeEach函数。将DB对象预加载为“fixtures”有时在Rails社区中完成。还有“工厂”的概念。每个战略都有优势和缺点。我不确定是否有工厂或灯具的节点库,但要进行网络搜索。

2

要增加Peter Lynos的建议,请允许我向您介绍单元测试的正确思路。在进行单元测试时,很多人会问错误的问题。这不是“我该如何测试”,而是“我要测试什么”。在你的情况下,你想测试你的代码,逻辑,而不是别的。这意味着您必须删除所有外部因素,包括第三方库,npm模块,甚至是node.js核心API模块。

问问你自己:你可以复制你的测试套件并运行它,而无需花费几个小时来设置环境?你应该能够。这就是编写单元测试的重点 - 使其单独运行以确保代码正确。我们称之为“环境”,您的代码可以独立于“控制环境”运行,类似于科学界使用的相同术语。

现在要实现这一点,您需要了解灯具和嘲笑的概念。有灯具可以创造你的控制环境。它通过创建一堆模拟对象来实现,其中每个模拟对象接受输入并生成输出。通过这种方式,您可以精确控制代码的各个方面,并且使测试从DB操作到REST请求的各种东西变得非常简单。

最后,在理解的是:

  1. 最好测试套件是一个可以在一个孤立的,控制环境
  2. 夹具被用来创建该环境通过提供您的代码与模拟对象
  3. 运行
  4. 模拟对象需要输入并返回输出
  5. 以上三件事情只有在您已经用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才会在您的项目中变得有趣。希望这可以帮助!