SINON存根不使用模块。导出={f1,f2}

我有如下发送OTP的文件。

OtpService.js

const generateOTP = async function() {
 //
}

const verifyOTP = async function() {
//
}

module.exports = {
 generateOTP,
 verifyOTP
}

下面是使用这些方法的控制器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')
  });
});

以上不起作用,在控制器中调用时不会截断generateOTPverifyOTP方法。

但是,如果我在otp.test.js中调用OtpService.generateOTP(),则它在那里工作,但在控制器中不工作。

辛农在这里的工作情况如何?

我这里搞糊涂了。 先要求应用程序,然后进行存根是正确的,还是先进行存根,然后再要求是正确的?

两种方法我都试过了,虽然都不管用。 我还尝试使用before() and beforeEach()

下面是我的文件夹结构。

otp.js(控制器)在此controller->AuthController->otp.js

otp.test.js在此test->auth->otp.test.js

OtpService.js就在services

内部

更新

我发现了问题所在。 如果我不在控制器中使用析构功能,一切都会正常工作。因此,使用OtpService.generateOTP有效。

问题与对象的析构有关。

const { verifyOTP, generateOTP } = require('../../services/OtpService')
上面的是在存根之前运行的。因此verifyOTPgenerateOTP已经引用了unstubbed方法。

我需要解决此问题。我要使用析构功能。


解决方案

我使用proxyquire包来存根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

相关文章