如何使用sinon对在节点js中api请求上调用的函数进行存根

问题描述 投票:0回答:1
//routes.js
app.get('/:id/info',
    UnoController.getGameInfo,
    ...
);

//UnoController.js
async function getGameInfo(req, res) {
    data = await UnoModel.getGameInfo(req.params.id);
    if(data==null) return res.status(404).json({message:'Room Not Found'});
    res.json(data);
}


//UnoModel.js
exports.getGameInfo = async function (id) {
    return await mongodb.findById('uno', id);
}

我正在使用sinon在节点js中编写单元测试。我想存根UnoModel.getGameInfo返回{id:'123456789012'},当我点击/someid/info rest api。

我写了如下的测试用例。

//UnoApiTest.js
it('get game info with player payload and invalid room id', function (done) {
    sinon.stub(UnoModel, 'getGameInfo').resolves({ id: '123456789012' });
    request({
        url: 'http://localhost:8080/api/v1/game/uno/123456789012/info',
        headers: { 'x-player-token': jwt.sign({ _id: '123' }) }
    }, function (error, response, body) {
        expect(response.statusCode).to.equal(200);
        done();
    });
});

但是我收到的statusCode为404。我试图控制数据。它实际上是从数据库获取的。它不返回存根提供的值。谁能帮我这个?还有其他方法吗?

javascript node.js unit-testing integration-testing sinon
1个回答
0
投票

它应该工作。例如:

server.js

const express = require('express');
const UnoController = require('./UnoController');
const app = express();

app.get('/api/v1/game/uno/:id/info', UnoController.getGameInfo);

module.exports = app;

UnoController.js

const UnoModel = require('./UnoModel');

async function getGameInfo(req, res) {
  const data = await UnoModel.getGameInfo(req.params.id);
  if (data == null) return res.status(404).json({ message: 'Room Not Found' });
  res.json(data);
}

exports.getGameInfo = getGameInfo;

UnoModel.js

// simulate mongodb
const mongodb = {
  findById(arg1, arg2) {
    return { name: 'james' };
  },
};
exports.getGameInfo = async function(id) {
  return await mongodb.findById('uno', id);
};

UnoApiTest.test.js

const app = require('./server');
const UnoModel = require('./UnoModel');
const request = require('request');
const sinon = require('sinon');
const { expect } = require('chai');

describe('61172026', () => {
  const port = 8080;
  let server;
  before((done) => {
    server = app.listen(port, () => {
      console.log(`http server is listening on http://localhost:${port}`);
      done();
    });
  });
  after((done) => {
    server.close(done);
  });
  it('should pass', (done) => {
    sinon.stub(UnoModel, 'getGameInfo').resolves({ id: '123456789012' });
    request({ url: 'http://localhost:8080/api/v1/game/uno/123456789012/info' }, function(error, response, body) {
      expect(response.statusCode).to.equal(200);
      done();
    });
  });
});

带有覆盖率报告的API自动化测试结果:

  61172026
http server is listening on http://localhost:8080
    ✓ should pass


  1 passing (50ms)

------------------|---------|----------|---------|---------|-------------------
File              | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------------|---------|----------|---------|---------|-------------------
All files         |      80 |       50 |   33.33 |   85.71 |                   
 UnoController.js |   83.33 |       50 |     100 |     100 | 5                 
 UnoModel.js      |      50 |      100 |       0 |      50 | 4,8               
 server.js        |     100 |      100 |     100 |     100 |                   
------------------|---------|----------|---------|---------|-------------------

源代码:https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/61172026

© www.soinside.com 2019 - 2024. All rights reserved.