【问题标题】:how to use sinon js with Express js unit testing如何在 Express js 单元测试中使用 sinon js
【发布时间】:2017-02-06 10:15:33
【问题描述】:

嗨,我想对我的 express js 代码进行单元测试,我想模拟数据,所以在搜索了多个网站和博客后,我找到了 this 库,但我不清楚如何使用这个库来模拟或数据。 我的测试代码是

var request = require('supertest');
var server = require('./app');
var chai = require('chai');
var chaiHttp = require('chai-http');

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

var should = chai.should();
chai.use(chaiHttp);

describe('loading express', function () {

  it('responds to /', function testSlash(done) {
    request(server)
      .get('/')
      .expect(200, done);
  });

  it('404 everything else', function testPath(done) {
    request(server)
      .get('/foo/bar')
      .expect(404, done);
  });

  it('responds to /customers/getCustomerData', function testPath(done) {
    request(server)
      .get('/customers/getCustomerData?id=0987654321')
      .end(function(err, res){
        res.should.have.status(200);
        res.body.should.be.a('object');
        res.body.status.should.equal("success");
        res.body.data.customerId.should.equal("0987654321");

        done();
      });
  });

});

目前此代码正在从数据库中获取数据,但我希望使用模拟数据进行单元测试。我怎样才能做到这一点?

__EDIT__

我想测试写在 Express js 路由文件中的代码。我在像这样的 app.js 文件中调用这条路线

var customers = require('./routes/customers');
app.use('/customers', customers);

现在 customers route 文件包含的代码是

function getCustomerData(req, res, next) {
    var response = {};
    var cb = function (response) {
        res.send(response);
    }
    var modelObj = req.models.customer_master;
    var data = req.query;
    controllers.customers.get(modelObj, data, cb);
};
router.get('/getCustomerData', function (req, res, next) {
    getCustomerData(req, res, next);
});

我想使用模拟数据测试“get”方法的响应

【问题讨论】:

  • 您可以使用 passthrough() 模拟响应,例如 var response=new passthrough() 但由于您使用的是 supertest,您可以检查我的答案,其中包含您要求的测试文件。查看日期,您可能已经找到了解决方案,但是,如果有帮助,请告诉我。

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


【解决方案1】:

另外,如果你写了很多测试文件,存根可能因为缓存而无法工作。在初始化存根和服务器之前,我必须清除缓存。顺序也很重要。

// have to clear every module which belongs to the require chain
// APP require FOO ROUTE require FOO CONTROLLER require BAR LIB
const caches = [
    '../app',
    '../routes/foo',
    '../controller/foo',
];
caches.forEach(cache => {
    delete require.cache[require.resolve(cache)];
});
// mock
const bar = require('../lib/bar');
sinon.stub(bar, 'bar').callsFake(async function() {
    return null;
});
app = require('../app');

// ... then the test ...

我发现this thread 很有帮助。

【讨论】:

    【解决方案2】:

    如果你想模拟,你可以使用 sinon express mocks here 或者如果你想测试实际的响应数据,JSON,使用这个example

    快速路由,在示例中,带一个参数并返回一个 JSON

    it('should respond with JSON data', function (done) {
      request(server)
        .get('/about/jv')
        .expect(200)
        .end(function (err, response) {
          assert.equal(response.header['content-type'], 'application/json; charset=utf-8');
          assert.deepEqual(response.body, {
            "data":{
            "username":"hellojv"}
          });
          done();
        });
    

    但是如上所述,如果您想使用 sinon,请使用 mock 库。该示例使用 Mocha 和 supertest。

    【讨论】:

      【解决方案3】:

      我猜你想存根你的控制器中间件。由于您没有提供任何服务器端代码,我只是假设一些事情:

      app.get('/', rootController.get);
      

      现在你想存根这个控制器:

      it('responds to /', function testSlash(done) {
        const rootController = require('./path/to/your/controller');
        const rootControllerStub = sinon.stub(rootController, "get",
          function(req, res, next){
            res.status(200).json({stubbed: 'data'});
          });
        request(server)
          .get('/')
          .expect(200)
          .expect({stubbed: 'data'})
          .end(done);
      });
      

      【讨论】:

      • 实际上代码是写在 Express js 路由文件中的,我想测试这段代码,但它没有像“get”这样的方法。为了更清楚,我正在编辑我的问题。谢谢
      • 那么只模拟你不想测试的东西,在你的情况下是 controllers.customers.get
      • 在您给出的示例中,测试是否保证通过?
      • @Embedded_Mugs 在我的示例中是的,OP 只想测试可以通过此完成的快速路由。如果路由不存在,则测试将失败。控制器前面的一些故障中间件也是如此。get fn
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-16
      • 2020-05-04
      • 1970-01-01
      • 2018-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多