javascript - 使用 rewire stub 独立的 module.exports 函数

标签 javascript node.js mocha.js sinon

我正在尝试 stub 一个module.exports函数。但我有一些麻烦。我会给你一个情况的sudo代码。

MyController.js

const sendOTPOnPhone = rewire('../../src/services/OtpService/sendOTPOnPhone')

module.exports = async function(req, res) {
         const { error, data } = await sendOTPOnPhone(req.query.phone) //this is I want to stub
         if(error)
           return return res.send(error)
         return res.send(data)
}

sendOTPService.js

module.exports = async function(phone) {
               const result = await fetch(`external-api-call`)
               if(result.status !== 'success')
                  return {
                          error: "Failed to send OTP!",
                          data: null
                  }
               return {
                      error: null,
                      data: result
               }
}

sendOTPTest.js

const expect = require('chai').expect
const request = require('supertest')
const sinon = require('sinon')
const rewire = require('rewire')
const sendOTPOnPhone = rewire('../../src/services/OtpService/sendOTPOnPhone')

const app = require('../../src/app')

describe('GET /api/v1/auth/otp/generate', function () {
    it('should generate OTP', async () => {
        let stub = sinon.stub().returns({
            error: null,
            data: "OTP sent"
        })
        sendOTPOnPhone.__set__('sendOTPOnPhone', stub)
        const result = await request(app)
            .get('/api/v1/auth/otp/generate?phone=8576863491')
            .set('Accept', 'application/json')
            .expect('Content-Type', /json/)
            .expect(200)
        expect(stub.calledOnce).to.be.true
        console.log(result.body)
        // expect(result).to.equal('promise resolved'); 
    })
})

以上测试失败,未调用 stub 。我不知道我错过了什么?如果我在 sendOTPService 中执行此操作:

const sendOTP = async function() {}
module.exports = {
  sendOTP
}

这在 Controller 中。

const { error, data } = sendOTPOnPhone.sendOTPOnPhone(req.query.phone)

它有效。

但我像 const {sendOTPOnPhone } = require('../sendOTPService') 一样导入它,但它不起作用。

我知道破坏会改变对象的引用。
有人可以提出解决方法吗?
是否可以使用rewire来实现这一点?或者可以使用 proxyquire 来完成。
请问有人可以建议吗?

最佳答案

这是使用 proxyquire 的集成测试解决方案,你应该使用 Globally override require .

app.js:

const express = require('express');
const controller = require('./controller');

const app = express();
app.get('/api/v1/auth/otp/generate', controller);

module.exports = app;

controller.js:

let sendOTPOnPhone = require('./sendOTPOnPhone');

module.exports = async function(req, res) {
  const { error, data } = await sendOTPOnPhone(req.query.phone);
  if (error) return res.send(error);
  return res.send(data);
};

sendOTPOnPhone.js:

module.exports = async function(phone) {
  const result = await fetch(`external-api-call`);
  if (result.status !== 'success')
    return {
      error: 'Failed to send OTP!',
      data: null,
    };
  return {
    error: null,
    data: result,
  };
};

sendOTP.test.js:

const request = require('supertest');
const sinon = require('sinon');
const proxyquire = require('proxyquire');

describe('GET /api/v1/auth/otp/generate', function() {
  it('should generate OTP', async () => {
    let stub = sinon.stub().resolves({
      error: null,
      data: { message: 'OTP sent' },
    });
    stub['@global'] = true;
    const app = proxyquire('./app', {
      './sendOTPOnPhone': stub,
    });
    const result = await request(app)
      .get('/api/v1/auth/otp/generate?phone=8576863491')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200);
    sinon.assert.calledOnce(stub);
    console.log(result.body);
  });
});

集成测试结果与覆盖率报告:

  GET /api/v1/auth/otp/generate
{ message: 'OTP sent' }
    ✓ should generate OTP (2373ms)


  1 passing (2s)

-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   68.75 |       25 |      50 |   73.33 |                   
 app.js            |     100 |      100 |     100 |     100 |                   
 controller.js     |   83.33 |       50 |     100 |     100 | 5                 
 sendOTPOnPhone.js |      20 |        0 |       0 |      20 | 2-4,8             
-------------------|---------|----------|---------|---------|-------------------

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

关于javascript - 使用 rewire stub 独立的 module.exports 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60599945/

相关文章:

javascript - 固定标题和侧边栏但可滚动的内容和标题区域

javascript - Angular 2 ngModel不绑定(bind)类定义中定义的对象属性

javascript - 如何将 Mocha 与 Promises/ES6 生成器一起使用?

javascript - Karma 运行程序在 TDD 上因解析错误而退出

javascript - 在 Node.js 中监视 require

javascript - 如何检测事件是否是浏览器事件

javascript - 如何在不四舍五入的情况下格式化 float ?

mysql - 在Sequelize的FROM子句中指定子查询

node.js - 如何使用pm2运行 `webpack --watch`?

javascript - 同步功能node.js与postgresql?