[英]How to mock Twilio using Jest and TypeScript for unit testing
I need your help to mock a twilio service which sends a message, using jest to mock the service I have the next code:我需要您的帮助来模拟发送消息的 twilio 服务,使用玩笑来模拟服务我有下一个代码:
import { SQSEvent } from "aws-lambda";
import { GetSecretValueResponse } from "aws-sdk/clients/secretsmanager";
export async function sendSms(event: SQSEvent, data: GetSecretValueResponse) {
const secrets = JSON.parse(data.SecretString);
const accountSid = secrets.TWILIO_ACCOUNT_SID;
const authToken = secrets.TWILIO_AUTH_TOKEN;
const twilioNumber = secrets.TWILIO_PHONE_NUMBER;
if (accountSid && authToken && twilioNumber) {
//Create a Twilio Client
const client = new Twilio(accountSid, authToken);
//Loop into al records of the event, every record is every message sent from Sqs
for (const record of event.Records) {
const body = JSON.parse(record.body);
const userNumber = "+" + body.number;
//SendMessage function
try {
const message = client.messages.create({
from: twilioNumber,
to: userNumber,
body: body.message,
});
return message;
} catch (error) {
return `Failed to send sms message. Error Code: ${error.errorCode} / Error Message: ${error.errorMessage}`;
}
}
} else {
return "You are missing one of the variables you need to send a message";
}
}
The I call this function from my index:我从我的索引中称之为 function:
import { SQSEvent } from "aws-lambda";
import { sendSms } from "./services/sendSms/sendSms";
import { getSecret } from "./services/obtainSecrets/getSecret";
import { SecretsManager } from "aws-sdk";
export const lambdaHandler = async (event: SQSEvent) => {
try {
const obtainedSecret = await getSecret()
.then((credentials: SecretsManager.GetSecretValueResponse) => {
return credentials;
})
.catch(error => {
return error;
});
const response = sendSms(event, obtainedSecret)
.then(response => {
return response;
})
.catch(error => {
return error;
});
return {
message: "OK " + obtainedSecret + response,
code: 200,
};
} catch (error) {
throw new Error(error);
}
};
I have already make some tests, but them always makes a connection with Twilio api(requiring the real token, sid,etc), and I need to mock the Twilio service, so the function I call in my test.ts doesn't connects to internet.我已经进行了一些测试,但它们总是与 Twilio api 建立连接(需要真正的令牌、sid 等),并且我需要模拟 Twilio 服务,因此 ZC1C425268E68385D1AB5ZI074C 连接测试。到互联网。
I have tried this so far:到目前为止,我已经尝试过:
I tried to mock the Twilio library and my sendSms service.我试图模拟 Twilio 库和我的 sendSms 服务。
I have created a smsMessageResultMock to simulate a success response of sendSms.我创建了一个 smsMessageResultMock 来模拟 sendSms 的成功响应。
Then I update that smsMessageResultMock to simulate a failed response.然后我更新该 smsMessageResultMock 以模拟失败的响应。
Then I tried to create a client with mocked Twilio, so I can call the Twilio's messages.create to send a message and give it a jest.fn().mockResolvedValue({...smsMessageresultMock}).然后我尝试使用模拟的 Twilio 创建一个客户端,所以我可以调用 Twilio 的 messages.create 来发送消息并给它一个 jest.fn().mockResolvedValue({...smsMessageresultMock})。
At last, I expect that when I call the function sendSms(event,data) to throw an error and that error will be Failed to send sms message. Error Code: ${smsMessageMock.errorCode} / Error Message: ${smsMessageMock.errorMessage}
最后,我希望当我调用 function sendSms(event,data) 时抛出一个错误,该错误将是
Failed to send sms message. Error Code: ${smsMessageMock.errorCode} / Error Message: ${smsMessageMock.errorMessage}
Failed to send sms message. Error Code: ${smsMessageMock.errorCode} / Error Message: ${smsMessageMock.errorMessage}
import { Twilio } from "twilio";
import { MessageInstance } from "twilio/lib/rest/api/v2010/account/message";
import { sendSms } from "../../services/sendSms/sendSms";
//mock Twilio library and sendSms service
jest.mock("twilio");
jest.mock("../../services/sendSms/sendSms");
const smsMessageResultMock: Partial<MessageInstance> = {
status: "sent",
sid: "AC-lorem-ipsum",
errorCode: undefined,
errorMessage: undefined,
};
describe("SMS Service", () => {
describe("Send Message", () => {
it("Should fail", async () => {
// update smsMessageResultMock to simulate a faled response
const smsMessageMock = {
...smsMessageResultMock,
status: "failed",
errorCode: 123,
errorMessage: "lorem-ipsum",
};
// simulated response of secret management
let data = {
ARN: "arn:aws:secretsmanager:us-west-2:123456789012:secret:MyTestDatabaseSecret-a1b2c3",
Name: "MyTestDatabaseSecret",
SecretString:
'{"TWILIO_ACCOUNT_SID": "ACTWILIO_ACCOUNT_SID","TWILIO_AUTH_TOKEN": "TWILIO_AUTH_TOKEN","TWILIO_PHONE_NUMBER": "TWILIO_PHONE_NUMBER"}',
VersionId: "EXAMPLE1-90ab-cdef-fedc-ba987SECRET1",
VersionStages: ["AWSPREVIOUS"],
};
// simulated response of SqsEvent
let event = {
Records: [
{
messageId: "19dd0b57-b21e-4ac1-bd88-01bbb068cb78",
receiptHandle: "MessageReceiptHandle",
body: '{"message": "Hello world","number": "(506)88888888"}',
attributes: {
ApproximateReceiveCount: "1",
SentTimestamp: "1523232000000",
SenderId: "123456789012",
ApproximateFirstReceiveTimestamp: "1523232000001",
},
messageAttributes: {},
md5OfBody: "{{{md5_of_body}}}",
eventSource: "aws:sqs",
eventSourceARN: "arn:aws:sqs:us-east-1:123456789012:MyQueue",
awsRegion: "us-east-1",
},
],
};
// simulate tokens for Twilio
const accountSid = "ACfjhdskjfhdsiuy876hfijhfiudsh";
const authToken = "fjfuewfiuewfbodfiudfgifasdsad";
//create client with mocked Twilio
const client = new Twilio(accountSid, authToken);
//call messages.create of Twilio client, and give it the expected result created
client.messages.create = jest
.fn()
.mockResolvedValue({ ...smsMessageMock });
console.log(await sendSms(event, data));
//expectes the function sendSms(event, data) to throw an error
await expect(sendSms(event, data)).rejects.toThrowError(
`Failed to send sms message. Error Code: ${smsMessageMock.errorCode} / Error Message: ${smsMessageMock.errorMessage}`
);
});
});
});
(event and data are simulated responses of SqsEvent and GetSecretValueResponse) (事件和数据是 SqsEvent 和 GetSecretValueResponse 的模拟响应)
The problem is that when I run the npm test it throws me an error of Twilio's authentication, an it is because I'm passing self created tokens.问题是,当我运行 npm 测试时,它会抛出 Twilio 身份验证错误,这是因为我正在传递自创令牌。
Expected substring: "Failed to send sms message. Error Code: 123 / Error Message: lorem-ipsum"
Received message: "Authentication Error - invalid username"
at success (node_modules/twilio/lib/base/Version.js:135:15)
at Promise_then_fulfilled (node_modules/q/q.js:766:44)
at Promise_done_fulfilled (node_modules/q/q.js:835:31)
at Fulfilled_dispatch [as dispatch] (node_modules/q/q.js:1229:9)
at Pending_become_eachMessage_task (node_modules/q/q.js:1369:30)
at RawTask.Object.<anonymous>.RawTask.call (node_modules/asap/asap.js:40:19)
at flush (node_modules/asap/raw.js:50:29)
So what I suppose is that the test is connecting to internet and calling Twilio's api.所以我认为测试是连接到互联网并调用 Twilio 的 api。
I appreciate if you could help me.如果您能帮助我,我将不胜感激。
Edit, Im using SQS to get the number and the body of the message, and I get Twilio Token and Sid from Secret Management.编辑,我使用 SQS 获取消息的编号和正文,并从 Secret Management 获取 Twilio 令牌和 Sid。 I'm really new in unit testing, I have tried a lot, but I can't get it
我在单元测试方面真的很新,我尝试了很多,但我无法得到它
I think what you want to do is mock the class returned by the module, using jest.mock('twilio', mockImplementation)
and in mockImplementation
return a function to act as a constructor that will take your account SID and auth token arguments and then return a mockClient
implementation, which in this case needs to return an object which has a messages
property, which in turn is an object with a create
property that is a mock function. I think what you want to do is mock the class returned by the module, using
jest.mock('twilio', mockImplementation)
and in mockImplementation
return a function to act as a constructor that will take your account SID and auth token arguments and then返回一个mockClient
实现,在这种情况下需要返回一个具有messages
属性的 object,它又是一个 object,其create
属性是一个模拟 function。
It's probably easier to just show the code.只显示代码可能更容易。
const mockClient = {
messages: {
create: jest.fn().mockResolvedValue({ ...smsMessageMock });
}
};
jest.mock("twilio", () => {
return function(accountSid, authToken) {
return mockClient;
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.