我已经实现了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();
});
});
答案 0 :(得分:0)
首先,我们应该知道以下关于 Promise.promisifyAll 的事情:
<块引用>对象的整个原型链都在对象上进行了promisified。只考虑可枚举的。如果对象已经有方法的promisified 版本,它将被跳过。假设目标方法符合 node.js 回调约定,即接受回调作为最后一个参数,并使用错误作为第一个参数和第二个参数的成功值调用该回调。
有两种解决方案:
sendGridMail.send
替换为 Error-first callbacks。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"