【问题标题】:Test route and stub a function call within it?测试路由并在其中存根函数调用?
【发布时间】:2019-03-20 09:03:42
【问题描述】:

是否可以使用 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,
};

以及它的 Express 路线,在 ./routes.js

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 调用的正确方法是什么?我已经在网上搜索了几个小时,但没有遇到过类似案例的一个工作版本。

【问题讨论】:

    标签: node.js express mocha.js sinon chai


    【解决方案1】:

    你试过proxyquire吗?

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

    https://github.com/thlorenz/proxyquire

    所以你可以写

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

    【讨论】:

    • 谢谢,我今天晚些时候试试。
    • 好的,如果顺利的话告诉我
    • 很抱歉以这种方式与您联系(我的评论与您在此处的输入无关)。我遇到了一个你在“分类”中投票的问题,你做出了错误的选择。请:仔细研究分类帮助,避免将不属于那里的项目放入编辑队列。我希望您将此视为改善投票的机会。我特指stackoverflow.com/review/triage/21145745。如果您对我有其他问题或反馈,请随时给我留言。如果你给我一个快速的回复,我会立即在这里删除这条评论。
    【解决方案2】:

    使用 proxyquire 的替代方法是避免使用 import default

    您的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' ] });
    

    参考:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-07
      • 2018-06-16
      • 2016-12-24
      • 2010-12-20
      • 1970-01-01
      • 1970-01-01
      • 2016-05-26
      相关资源
      最近更新 更多