我一直在使用Jest对node进行单元测试。
我习惯于嘲笑模块/函数的第一级,但是在模仿Twilio的挑战中,我没有那么幸运。
我正在使用twilio方法:client.messages.create
,所以这里有来自构造函数require('twilio')(account sid, token)
的twilio客户端,第一层是来自对象/方法(?)messages
,最后是第三级create
,这就是我要嘲笑的最后一个家伙。
我正在尝试这样的事情:
jest.mock('twilio', () => {
const mKnex = {
messages: jest.fn(),
};
return jest.fn(mKnex);
});
但是,我无法模拟得到client
的{{1}}解析值。
如果尝试上面的模拟加上此client.message.create is not a function
,我将无法从client.messages.create.mockReturnValueOnce({sid: "FOO", status: "foo");
(消息)读取属性create
。
任何提示,帖子,文档都可以给我带来一些运气吗? 谢谢
答案 0 :(得分:0)
我找到了解决方案。它仍然在调用端点,但是对于每个twilio帐户,您都会得到一个测试SID和令牌,我使用了这个,因此在对此进行测试时它不会发送短信:
if (process.env.NODE_ENV !== 'test') {
client = require('twilio')(accountSid, authToken)
listener = app.listen(3010, function(){
console.log('Ready on port %d', listener.address().port)
})
}else{
client = require('twilio')(testSid, testToken)
}
答案 1 :(得分:0)
对此的解决方案是:
// sms.client.ts
import { Twilio } from 'twilio';
const smsClient = new Twilio(
'TWILIO-ACCOUNT-SID',
'TWILIO-TOKEN'
);
export { smsClient };
// sms.service.ts
import { smsClient } from './sms.client';
class SMSService {
async sendMessage(phoneNumber: string, message: string): Promise<string> {
const result = await smsClient.messages.create({
from: '(555) 555-5555',
to: phoneNumber,
body: message,
});
if (result.status === 'failed') {
throw new Error(`Failed to send sms message. Error Code: ${result.errorCode} / Error Message: ${result.errorMessage}`);
}
return result.sid;
}
}
export const smsService = new SMSService();
// sms.service.spec.ts
import { MessageInstance, MessageListInstance } from 'twilio/lib/rest/api/v2010/account/message';
import { smsClient } from './sms.client';
import { smsService } from './sms.service';
// mock the client file
jest.mock('./sms.client');
// fixture
const smsMessageResultMock: Partial<MessageInstance> = {
status: 'sent',
sid: 'AC-lorem-ipsum',
errorCode: undefined,
errorMessage: undefined,
};
describe('SMS Service', () => {
beforeEach(() => {
// stubs
const message: Partial<MessageListInstance> = {
create: jest.fn().mockResolvedValue({ ...smsMessageResultMock })
};
smsClient['messages'] = message as MessageListInstance;
});
it('Should throw error if response message fails', async () => {
// stubs
const smsMessageMock = {
...smsMessageResultMock,
status: 'failed',
errorCode: 123,
errorMessage: 'lorem-ipsum'
};
smsClient.messages.create = jest.fn().mockResolvedValue({ ...smsMessageMock });
await expect(
smsService.sendMessage('(555) 555-5555', 'lorem-ipsum')
).rejects.toThrowError(`Failed to send sms message. Error Code: ${smsMessageMock.errorCode} / Error Message: ${smsMessageMock.errorMessage}`);
});
describe('Send Message', () => {
it('Should succeed when posting the message', async () => {
const resultPromise = smsService.sendMessage('(555) 555-5555', 'lorem-ipsum');
await expect(resultPromise).resolves.not.toThrowError(Error);
expect(await resultPromise).toEqual(smsMessageResultMock.sid);
});
});
});