测试路由并在其中添加函数调用?

时间:2018-10-15 21:41:38

标签: node.js express mocha sinon chai

是否可以使用Mocha和Sinon在Express路由中添加功能?

这里是./apps/stuff/controller.js

中的实现
import db from '../lib/database';

const getStuff = async (req, res) => {
  const results = await db.query(req.id); // I want to stub this
  return res.status(200).json({
    thingy: results.thingy,
    stuff: [
      results.foo,
      results.bar,
    ],
  });
};

export default {
  getStuff,
};

以及./routes.js中的Express路线

import stuff from './apps/stuff/controller';
import express from 'express';

const app = express();

app.route('/stuff')
  .get(stuff.getStuff);

因此,在测试用例中,我想将对db.query()的调用存根,而是在GET /stuff请求运行测试期间返回自定义结果。

// ./test/stuff/controller.js
import db from '../../apps/lib/database';

import chai from 'chai';
import chaiHttp from 'chai-http';
import server from '../../index';

const { expect } = chai;

chai.use(chaiHttp);

describe('getStuff', () => {
  it('gets you stuff', async () => {
    // I have tried this, but it results in TypeError: Cannot stub non-existent own property query
    // I presume it is creating a new "empty" object instead of stubbing the actual implementation
    sandbox.stub(db, 'query').resolves({ thingy: 'bar', stuff: [ 123, 'wadsofasd' ] });

    chai.request(server)
      .get('/stuff?id=123')
      .then(res => {
        expect(res).to.have.status(200);
        expect(res.body).to.deep.equal({
          thingy: 'bar',
          stuff: [
            123,
            'wadsofasd',
          ]
        });
      }); 
  });
});

在上述情况下,对db.query调用进行存根/模拟的正确方法是什么?我已经在网上搜索了几个小时,但没有遇到类似案例的单个工作版本。

2 个答案:

答案 0 :(得分:0)

您尝试过proxyquire吗?

Proxyquire是一个JavaScript库,用于欺骗node.js所需,因此您可以在检测到require('example / route / of / your / import')时将其传递给另一个函数(您的存根)。

https://github.com/thlorenz/proxyquire

所以你可以写

    const proxyquire = require('proxyquire');

    proxyquire('./apps/stuff/controller', {
        getStuff: sandbox.stub()
    }

答案 1 :(得分:0)

除了使用proxyquire之外,另一种方法是避免使用导入默认值

您的db模块看起来像使用export default(它不会作为符号导出),并使sinon无法正确地对它进行存根。

解决方案使用命名的导出

database.js

export function query() {
 // implementation
}

=== OR ===

function query() { .. }

module.exports = {
  query
}

stuff / controller.js

import * as db from '../lib/database'; // alternative => import { query } from '...'

const getStuff = async (req, res) => {
  const results = await db.query(req.id); // I want to stub this
  // ...
};

test / stuff / controller.js

import * as db from '../../apps/lib/database';

// ...

sandbox.stub(db, 'query').resolves({ thingy: 'bar', stuff: [ 123, 'wadsofasd' ] });

参考: