javascript - Sinon stub 无法与 module.exports = { f1, f2} 一起使用

标签 javascript node.js integration-testing sinon supertest

我有这个文件,它发送如下所示的 otp。

OtpService.js

const generateOTP = async function() {
 //
}

const verifyOTP = async function() {
//
}

module.exports = {
 generateOTP,
 verifyOTP
}

下面是使用这些方法的 Controller ,otp.js

const { verifyOTP, generateOTP } = require('../../services/OtpService')

const verify = async function(req, res) {
 const {error, data} = await generateOTP(req.query.phone)
}

const send = async function(req, res) {
 const {error, data} = await verifyOTP(req.query.phone, req.query.otp)
}

module.exports = {
 send,
 verify
}

下面是测试文件otp.test.js

const sinon = require('sinon');
const expect = require('chai').expect
const request = require('supertest')
const OtpService = require('../../src/services/OtpService')
console.log(OtpService)
describe('GET /api/v1/auth/otp', function() {
  let server 
  let stub
  const app = require('../../src/app')
  stub = sinon.stub(OtpService, 'generateOTP').resolves({
    error: null,
    data: "OTP Sent"
  })
  server = request(app)
  it('should generate OTP', async () => {
    const result = await server
        .get('/api/v1/auth/otp/send?phone=7845897889')
        .set('Accept', 'application/json')
        .expect('Content-Type', /json/)
        .expect(200)
        console.log(result.body)
    expect(stub.called).to.be.true
    expect(result).to.be.a('Object')
  });
});

上面不起作用,在 Controller 中调用时,它不会 stub generateOTPverifyOTP 方法。

但是,如果我在 otp.test.js 中调用 OtpService.generateOTP() ,那么它在那里工作,但在 Controller 中不起作用。

sinon 是如何在这里工作的?

我在这里很困惑。 要求应用程序然后 stub 正确还是先 stub 然后要求正确?

两种方法我都试过了,但都不起作用。 我还尝试使用 before() 和 beforeEach()

下面是我的文件夹结构。

enter image description here

otp.js( Controller )在这里controller->AuthController->otp.js

otp.test.js 在这里 test->auth->otp.test.js

OtpService.js 就在 services

更新

我发现了问题所在。 如果我不在 Controller 中使用破坏功能,一切都会正常工作。因此,使用 OtpService.generateOTP 是有效的。

问题在于对象的破坏。

const { verifyOTP, generateOTP } = require('../../services/OtpService')

上面是在 stub 之前运行的。因此,verifyOTPgenerateOTP 已经引用了 unstubbed 方法。

我需要一个解决方法。我想使用破坏功能。

最佳答案

我使用proxyquire打包到 stub OtpService 模块。下面的示例是单元测试,但您可以使用这种方式进行集成测试。

例如

otp.js:

const { verifyOTP, generateOTP } = require('./OtpService');

const verify = async function(req, res) {
  return generateOTP(req.query.phone);
};

const send = async function(req, res) {
  return verifyOTP(req.query.phone, req.query.otp);
};

module.exports = {
  send,
  verify,
};

OtpService.js:

const generateOTP = async function() {
  //
};

const verifyOTP = async function() {
  //
};

module.exports = {
  generateOTP,
  verifyOTP,
};

otp.test.js:

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

describe('60704684', () => {
  it('should send', async () => {
    const otpServiceStub = {
      verifyOTP: sinon.stub().resolves({ error: null, data: 'fake data' }),
      generateOTP: sinon.stub(),
    };
    const { send } = proxyquire('./otp', {
      './OtpService': otpServiceStub,
    });
    const mReq = { query: { phone: '123', otp: 'otp' } };
    const mRes = {};
    await send(mReq, mRes);
    sinon.assert.calledWithExactly(otpServiceStub.verifyOTP, '123', 'otp');
  });

  it('should verfiy', async () => {
    const otpServiceStub = {
      verifyOTP: sinon.stub(),
      generateOTP: sinon.stub().resolves({ error: null, data: 'fake data' }),
    };
    const { verify } = proxyquire('./otp', {
      './OtpService': otpServiceStub,
    });
    const mReq = { query: { phone: '123' } };
    const mRes = {};
    await verify(mReq, mRes);
    sinon.assert.calledWithExactly(otpServiceStub.generateOTP, '123');
  });
});

带有覆盖率报告的单元测试结果:

  60704684
    ✓ should send (1744ms)
    ✓ should verfiy


  2 passing (2s)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |     100 |      100 |      50 |     100 |                   
 OtpService.js |     100 |      100 |       0 |     100 |                   
 otp.js        |     100 |      100 |     100 |     100 |                   
---------------|---------|----------|---------|---------|-------------------

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

关于javascript - Sinon stub 无法与 module.exports = { f1, f2} 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60704684/

相关文章:

Node.js https pem 错误 : routines:PEM_read_bio:no start line

node.js - 向 module.exports 添加参数?

jquery - 使用 AJAX 的标准事件消息传递系统?

c# - 如何在 .NET 中使用真实文件进行集成测试?

ruby-on-rails - 为我在 Rails 3 中进行集成测试的方法提供帮助

javascript - 使用 Testcafe 访问自定义窗口属性

javascript - 使用 JavaScript 将字符串中的相对链接图像替换为绝对路径图像

node.js - 错误 : EXDEV: cross-device link not permitted, 在 Ubuntu 16.04 LTS 上重命名 '/tmp/

javascript - jQuery根据滚动定位增加和减少div高度

javascript - 如何使用 querySelector 选择下一个直接子级?