【问题标题】:Stubbing module in a running node server for testing edge cases运行节点服务器中的存根模块,用于测试边缘案例
【发布时间】:2016-01-18 22:54:38
【问题描述】:

我对@9​​87654323@ 及其测试生态系统还很陌生,所以如果这有点草率,请原谅我。

我正在尝试存根设置为原型属性的函数。这个函数,Validate.prototype.isAllowed,在我的服务器代码中被调用:

// Server
var router = require('express').Router();
var Validate = require('path/to/validator');
router.post('/jokes', function(req, res) {
  var validate = new Validate();
  if (!validate.isAllowed(req, 'jokes-create')) return res.end(403);
  res.end(200);
});

验证器代码如下所示:

// Validator
var validate = function() {};
validate.prototype.isAllowed = function(req, action) {
  return true; // make things simple
};
module.exports = validate;

我针对之前启动的服务器运行 API 测试。这是我的 Mocha 测试,我使用 sinon 来存根原型函数调用:

// Test
var Validate = require('path/to/validator');
var sinon = require('sinon');
var request = require('supertest-as-promised');
it('Fails with insufficient permissions', function(done) {
  sinon.stub(Validate.prototype, 'isAllowed', function() {
    return false;
  });
  request('www.example.com')
    .post('/jokes')
    .expect(403)
    .then(function() {
      Validate.prototype.isAllowed.restore();
      done();
    })
    .catch(done);
});

我观察到存根函数从未被调用并且测试从未通过。问题在哪里?

我还尝试向存根添加两个参数,但这似乎没有帮助。看起来像 this question 谈论同样的问题,但对于常规实例方法。此外,如果我将 sinon.stub() 位从测试移动到服务器,所需的存根就会生效。我感觉我的测试不会修补正在运行的服务器代码...

【问题讨论】:

    标签: node.js unit-testing express mocking sinon


    【解决方案1】:

    我认为在您的测试中,您应该创建一个新的验证器,然后为该验证器创建一个存根,而不是为原型创建一个存根。

    试试这个:

    it('Fails with insufficient permissions', function(done) {
      var validate = new Validate();
      sinon.stub(validate, 'isAllowed', function() {
        return false;
      });
      request('www.example.com')
        .post('/jokes')
        .expect(403)
        .then(function() {
          validate.isAllowed.restore();
          done();
        })
        .catch(done);
    });
    

    另外,我不熟悉 .restore() 函数,但由于 isAllowed 是一个函数,我相信调用

    validate.isAllowed.restore();
    

    不会工作。 (或者我错过了什么?)

    【讨论】:

    • 不幸的是,这不起作用。这个在Validate 的实例上存根isAllowed 方法,但是这个实例永远不会被使用——服务器在每次调用服务器路由时都会实例化一个新的验证器。
    • 有道理。您的原始函数是否被调用?在测试之外定义的那个。
    • 是的。另一个观察结果是,如果我将sinon.stub() 移动到服务器代码(就在路由处理程序定义之前),则会调用存根方法。看起来服务器上的库没有被存根,否则......
    • 我明白了。很抱歉无法提供帮助。我也对此很陌生。我会尝试做的是记录这两个验证器(测试和服务器)并检查它们的原型,我认为您正在更改两个不同的原型,但我只是在猜测。在存根和重新定义原型之后调用那个或者你的验证器。
    【解决方案2】:

    问题是服务器和测试在不同的进程中。应该从测试进程中启动服务器以使存根工作。

    这里有一个 example self-contained Gist 来说明这个想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-06
      • 1970-01-01
      相关资源
      最近更新 更多