Nodejs单元测试网址

时间:2011-05-12 06:22:20

标签: unit-testing url testing node.js asynchronous

以递增方式执行此操作的最佳方法是什么? 例如。有些网址必须先访问其他网址以填充数据库等。是否有一个惯用的节点单元测试方式?

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

2 个答案:

答案 0 :(得分:2)

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

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

现在要实现这一点,你需要了解灯具和模拟的概念。夹具可以创建您的控制环境。它通过创建一组模拟对象来实现,其中每个模拟对象获取输入并生成输出。通过这种方式,您可以精确控制代码的各个方面,并且可以轻松地测试从数据库操作到REST请求的各种内容。

最后,明白了:

  1. 最好的测试套件是可以在隔离的控制环境中运行的测试套件
  2. 通过为代码提供模拟对象来使用Fixtures来创建该环境
  3. 模拟对象接受输入并返回输出
  4. 只有使用100%注入依赖项编码项目
  5. ,才能实现上述3项内容

    模拟对象

    假设在你的函数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社区中完成。还有“工厂”的概念。每种策略都有优点和缺点。我不确定是否有工厂或灯具的节点库,但是进行网络搜索。