繁体   English   中英

Node.js单元测试

[英]Nodejs Unit Testing Urls

增量执行此操作的最佳方法是什么? 例如。 必须先访问某些URL才能填充数据库等。某些单元测试是否有惯用的节点方法?

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

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

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

现在要实现这一点,您需要了解固定装置和模拟装置的概念。 可以使用夹具来创建您的控制环境。 它是通过创建一堆模拟对象来实现的,每个模拟对象都接受一个输入并产生一个输出。 这样,您就可以完全控制代码的各个方面,这使得测试从DB操作到REST请求的所有内容变得非常简单。

最后,了解到:

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

模拟对象

假设您要在函数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 file 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才能在您的项目中变得有趣。 希望这可以帮助!

好的,一些技巧。 您的代码似乎根本没有使用任何测试框架,因此请至少查看使用commonJS断言或测试框架。 我更喜欢茉莉花 ,但是有几个很好的。 Jasmine对间谍程序和异步测试提供了强大的支持。 附带说明一下,这些不是单元测试,从定义上讲不会打入数据库,它们很可能是应用程序/系统测试。 除了这些通过整个堆栈发送实时数据的系统级测试之外,您可能还想考虑为服务器端代码编写一些纯单元测试。

关于测试先决条件的主题,通常尝试使每个测试尽可能独立。 但是,当无法避免完全独立时,大多数单元测试框架都有一个“ setup / teardown ”功能对的概念,这些功能在每次测试之前和之后都被调用。 jasmine中 ,这是beforeEach函数。 有时在Rails社区中将数据库对象预加载为“夹具”。 还有“工厂”的概念。 每种策略都有优点和缺点。 我不确定是否有用于工厂或固定装置的节点库,但可以进行网络搜索。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM