调用原始函数而不是存根

时间:2013-08-01 22:53:09

标签: javascript express mocha stub sinon

我遇到了让Sinon的存根正常工作的问题。当我在list上存根retro并且测试运行时,app.get('/retro', retro.list)正在执行原始函数retro.list而不是存根。由于发生这种情况,测试失败,因为存根callCount为0.

我对coffeescript比较熟悉,而且我用同样的方式抄袭了东西。是否有一些我不了解Javascript的范围,或require('../routes/retro')如何工作,或retroapp.jstest.js中是不一样的。

非常感谢下面的帮助和代码。

test.js:

var request = require('supertest')
  , retro = require('../routes/retro')
  , app = require('../app')
  , sinon = require('sinon');
require('should'); 

describe('GET /retro', function() {
  // less involved, but maybe stupid to test
  it('should call retro.list', function(done) {
    var stub = sinon.stub(retro, 'list');

    request(app)
      .get('/retro')
      .end(function(err, res){
        stub.callCount.should.equal(1);

        if (err) return done(err);
        done();
      })
  })
})

app.js:

var express = require('express')
  , config = require('./config')
  , routes = require('./routes')
  , retro = require('./routes/retro');

var app = express();
config(app);

app.get('/', routes.index);
app.get('/retro', retro.list);

module.exports = app;

retro.js:

var retro = {
  list: function(req, res){
    console.log('actual called');
    res.send("respond with a resource");
  }
}

module.exports = retro;

2 个答案:

答案 0 :(得分:8)

在要求/创建app之前,您可能需要创建存根。

var request = require('supertest')
  , sinon = require('sinon')
  , retro = require('../routes/retro');

var stubRetroList = sinon.stub(retro, 'list');

var app = require('../app');

// ...

    stubRetroList.callCount.should.equal(1);

这允许retro.list在传递到路径之前进行更新:

app.get('/retro', retro.list);

问题可能是因为retro.list没有被引用传递(指针),而是一个传递值(复制)的引用。因此,虽然sinon.stub()正在改变retro.list,但它不会影响'/retro'路径已经拥有的副本。

答案 1 :(得分:0)

我遇到了同样的问题,接受的答案(虽然是真的)没有任何帮助。结果是为了sinon存根工作,存根方法不能在同一模块中使用。换句话说,对模块端点进行存根只会存储模块端点,而不是module.exports引用的函数的内部用法。

通过一个例子解释:

module.js

const express = require('express')
const router = express.Router()

router.get('/', function (req, res) {
  res.status(200).json(list())
})

function list() {
    return ['something']
}

module.exports = {
    router: router,
    list: list
}

module.spec.js

// This stub will not work
sinon.stub(module, 'list').callsFake(() => ['something else'])

为了使它工作,你将你想要存根的东西分成它自己的模块并以这种方式使用它:

sub_module.js

function list() {
    return ['something']
}

module.exports = {
    list: list
}

现在sub_module.list()可以存根。

(OP定义了一种方法,所以这对他来说不是问题)