使用Sinon - Node.js,Mocha,Sinon存储第三个pary SDK

时间:2018-03-20 06:29:53

标签: javascript node.js mocha tdd sinon

我已经实现了Sendgird SDK来发送电子邮件,并且需要在我的测试中将其存根。我正在关注,错误

  

错误:超出2000毫秒超时。对于异步测试和挂钩,确保调用“done()”;如果返回Promise,请确保它已解决。

看来这个问题与测试执行时间无关,但有些与Promise有关。

这是原始课程,

import sendGridMail from '@sendgrid/mail';
import Promise from 'bluebird';

export default class sendGridClient {
  constructor() {
    this.apiKey = 'Test key';
    this.sendGrid = Promise.promisifyAll(sendGridMail);
    this.sendGrid.setApiKey(this.apiKey); 
 }

 async send(to, from, subject, description, body) {
   const message = {
     to,
     from,
     subject,
     text: description,
     html: body,
   };

   const response = await this.sendGrid.sendAsync(message);

   return response;
 }
}

测试代码,

import { expect } from 'chai';
import Promise from 'bluebird';
import sinon from 'sinon';
import sendGridMail from '@sendgrid/mail';

import sendGridClient from './../../../src/lib/sendGrid/sendGridClient';

 describe.only('sendGridClient', function () {
   it('sends email successfully', async function () {
     const sendGrid = Promise.promisifyAll(sendGridMail);

     const setApiKey = sinon.stub(sendGrid, 'setApiKey');
     const mandrillSend = sinon
      .stub(sendGrid, 'send')
      .returns(Promise.resolve({}));

     const sendGridApi = new sendGridClient();
     const actualResult = await sendGridApi.send(
       'supprt@test.com',
       'user@gmail.com',
       'Subject',
       'Email description',
       'Email body',
     );

     expect(mandrillSend.callCount).to.equal(1);

     setApiKey.restore();

     mandrillSend.restore();
  });
});

1 个答案:

答案 0 :(得分:0)

首先,我们应该知道以下关于 Promise.promisifyAll 的事情:

<块引用>

对象的整个原型链都在对象上进行了promisified。只考虑可枚举的。如果对象已经有方法的promisified 版本,它将被跳过。假设目标方法符合 node.js 回调约定,即接受回调作为最后一个参数,并使用错误作为第一个参数和第二个参数的成功值调用该回调。

有两种解决方案:

  1. sendGridMail.send 替换为 Error-first callbacks
  2. 存根 promisified 方法,它的名称将是带有 suffix 后缀的原始方法名称(默认为 "Async")。

例如

sendGridClient.test.js

// @ts-nocheck
import { expect } from 'chai';
import sinon from 'sinon';
import sendGridMail from '@sendgrid/mail';
import sendGridClient from './sendGridClient';

describe('sendGridClient', function () {
  it('should send email successfully (replace send method with stub)', async function () {
    const sendOriginal = sendGridMail.send;
    const setApiKey = sinon.stub(sendGridMail, 'setApiKey').returns('mocked');
    const mandrillSend = sinon.stub().callsFake((data, cb) => {
      cb(null, {});
    });
    sendGridMail.send = mandrillSend;
    const sendGridApi = new sendGridClient();

    const actualResult = await sendGridApi.send(
      'supprt@test.com',
      'user@gmail.com',
      'Subject',
      'Email description',
      'Email body',
    );
    expect(actualResult).to.be.deep.equal({});
    sinon.assert.calledWith(setApiKey, 'Test key');
    expect(mandrillSend.callCount).to.equal(1);

    setApiKey.restore();
    sendGridMail.send = sendOriginal;
  });

  it('sends email successfully (stub sendAsync method)', async function () {
    const setApiKey = sinon.stub(sendGridMail, 'setApiKey').returns('mocked');
    const sendGridApi = new sendGridClient();
    const mandrillSend = sinon.stub(sendGridMail, 'sendAsync').resolves({});

    const actualResult = await sendGridApi.send(
      'supprt@test.com',
      'user@gmail.com',
      'Subject',
      'Email description',
      'Email body',
    );
    expect(actualResult).to.be.deep.equal({});
    sinon.assert.calledWith(setApiKey, 'Test key');
    expect(mandrillSend.callCount).to.equal(1);

    setApiKey.restore();
    mandrillSend.restore();
  });
});

单元测试结果:

  sendGridClient
    ✓ should send email successfully (replace send method with stub)
    ✓ sends email successfully (stub sendAsync method)


  2 passing (9ms)

-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |     100 |      100 |     100 |     100 |                   
 sendGridClient.ts |     100 |      100 |     100 |     100 |                   
-------------------|---------|----------|---------|---------|-------------------

软件包版本:"bluebird": "^3.7.2"