【问题标题】:How to test stubbed database queries如何测试存根数据库查询
【发布时间】:2014-11-06 02:28:04
【问题描述】:

我有一个看起来像这样的 Sails.Js 控制器

module.exports = {
  confirmID: function(req,res) {
    var uid = req.params.id;
     User.findOne({id:uid}).exec(function(err,user) {
       // ...
     });
  }
}

User 是一个sails-postgres 模型。我试过用 mocha、sinon 和 supertest 测试它,用这样的测试

describe('Controller', function() {
  var sandbox;

  before(function() {
    sandbox = sinon.sandbox.create();
    sandbox.stub(User, 'findOne');
  });

  after(function() {
    sandbox.restore();
  });

  describe('GET /confirmid/:id', function() {

    it('should do something', function(done) {
      request(sails.hooks.http.app)
        .get('/confirmid/123')
        .expect(200)
        .end(function(err,res) {
          sandbox.fakes[0].called.should.be.true;
          done();
        });
  });
});

如果我把它留在那个地方,它会出错,因为 exec 在未定义时被调用,但我似乎无法在没有错误或测试挂起的情况下存根嵌套的 exec 方法。有没有办法存根一系列方法调用,例如.find().exec()?还是我最好将其留给可以使用实际数据库进行测试的集成测试?

【问题讨论】:

    标签: node.js orm sails.js sinon


    【解决方案1】:

    假设您真的想要存根(不仅仅是间谍) - 您想要控制查询解析的内容,而不是简单地知道查询是否已执行。这是我对stub sails/waterline query methods 使用的内容。比如……

    var stubQueryMethod = require('stubQueryMethod');
    
    describe('Controller', function() {
      before(function() {
        stubQueryMethod(User, 'findOne', {
          id: 123,
          name: 'Fred Fakes'
        });
      });
    
      after(function() {
        User.findOne.restore();
      });
    
      describe('GET /confirmid/:id', function() {
        it('should do something', function(done) {
          request(sails.hooks.http.app)
            .get('/confirmid/123')
            .expect(200)
            .end(function(err,user) {
              user.should.have.property('name', 'Fred Fakes');
              done();
            });
        });
      });
    });
    

    来源:https://gist.github.com/wxactly/f2258078d802923a1a0d

    【讨论】:

      【解决方案2】:

      对于寻找存根或模拟水线模型的其他选项的人,我发现了以下四个选项:

      在评估了每一个之后,我决定使用 sails-mock-models,因为它易于理解,并且根据 npm 似乎是最常用的 Sails 模拟库:https://www.npmjs.com/package/sails-mock-models

      希望这对某人有所帮助!


      更新:我仍在使用sails-mock-models,这很容易,但有一些缺点,例如它无法返回被纳入 q.all(promiseArray).then() 的承诺称呼。如果我有时间调查其他选项或找到解决方法,我会在此处发布。

      【讨论】:

      • 我创建了一个问题来跟踪 Promise.all 场景,如果我能取得任何进展,我会通知您。如果有更多详细信息,请随时在此处添加:github.com/ryanwilliamquinn/sails-mock-models/issues/1
      • 谢谢!如果我发现任何其他问题,我会确保将它们发布到 github。非常感谢。
      【解决方案3】:

      这仅适用于使用 exec 的查询,并且它会重载所有 exec 调用,因此如果您尝试返回错误并且您有一个带有策略的控制器,并且该策略执行一个数据库查找,在点击您打算测试的控制器代码之前,您可能会在那里出错......这可以用stub.onCall(x) 修复,但它仍然有点不稳定。

      除了警告之外,这是我过去的做法:

      var path = require('path');
      var sinon = require('sinon');
      
      var Deferred = require(path.join(
        process.cwd(),
        'node_modules/sails',
        'node_modules/waterline',
        'lib/waterline/query/deferred'
      ));
      
      module.exports = function () {
        return sinon.stub(Deferred.prototype, 'exec');
      };
      

      假设你有以下服务,MyService:

      module.exports.dbCall = function (id, cb) {
      
        Model.findOne(id).exec(function (err, result) {
      
          if (err) {
            sails.log.error('db calls suck, man');
            return cb(err, null);
          }
      
          cb(null, result);
      
        });
      
      };
      

      您可以像这样测试错误情况:

      before(function () { 
        stub = databaseStub(); 
      });
      
      afterEach(function () { 
        stub.reset();
      });
      
      after(function () {
        stub.restore(); 
      });
      
      it('should return errors', function (done) {
      
        stub.onCall(0).callsArgWith(0, 'error');
      
        MyService.dbCall(1, function (err, results) {
          assert.equal(err, 'error');
          assert.equal(results, null);
          done();
        });
      
      });
      

      【讨论】:

        猜你喜欢
        • 2011-01-10
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-19
        • 1970-01-01
        • 2012-06-17
        相关资源
        最近更新 更多