在没有命中数据库的情况下测试Hapijs端点

sfa*_*ece 7 integration-testing node.js hapijs

我正在使用Hapi js开发restApi.该项目的结构如下:


   |-Root
      server.js
      |-router
         routes.js
      |-handlers
         authHandler.js
      |-db
         userDb.js
 

验证请求将命中routes.js并转发给authHandler.js,后者又调用userDb.js.userDb.js与数据库通信并将结果返回给authHandler.js,后者将响应返回给客户端.

我一直在尝试编写一个userDb.js不与数据库通信的测试

为此,我使用Hapi的注入能够在不实际启动服务器的情况下调用路由.我正在努力弄清楚如何模拟调用链中的数据库,以便我可以提供虚拟响应.

简而言之,我希望在测试时将userDb.js替换为mock.

sfa*_*ece 2

在上面@AlbertZaccagni的建议之后,我查阅了sinon的文档,并得出以下结论:

注意:我省略了一些声明当前问题的路线和其他非重要部分的代码。

假设 userDb.js 是连接到数据库的模块,并且我想模拟来自数据库的响应:

userDb.js 看起来像这样:

var db = require(/*path to db */);

module.exports.getUser = function(id, callback){
    db.query('sql query', function(err, rows){
        if(err){
           return callback(err);
        }
        return callback(null, rows[0]);/*returns the first object- 
        in the resultset from the database.*/
    });
}
Run Code Online (Sandbox Code Playgroud)

在我的测试文件夹中,我创建了一个名为 mytest.js 的文件,其中包含以下内容:

//don't forget to install sinon JS via npm
var sinon = require('sinon');
var server = require(/*path to hapi server*/); 
var userDb = require(/*path to the module we are stubbing/mocking*/);

describe('Stub test', function(){
   var options = {};
    options.method = 'GET';
    options.url = '/user/1';

    it('with stubbing', function(done) {
        var stub = sinon.stub(userDb, 'getUser', function(id, callback) {
            if (id < 5) {
                return callback(null, 100);/*in this case i'm just testing 
                to see if this function
                will get called instead- 
                of the actual function. That's why 100.*/
            }

            return new Error('test error');
        });
        server.inject(options, function(res) {
            var result = res.result;
            res.statusCode.should.equal(200);
            result.num.should.equal(100);
            done();
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

当我在工作目录上运行 npm test 时,我看到它通过了,而没有实际调用数据库,并且它为用户名 1 返回 100。