提问人:Abdul-Raffay 提问时间:9/18/2023 更新时间:9/18/2023 访问量:27
如何使用包含Joi的jest测试expressJS端点进行请求验证?
How to test a expressJS endpoint using jest which includes Joi for request validation?
问:
我一直在开发一个 expressJS 应用程序,其中我编写了一个端点,该端点向用户发送调用以进行 OTP 验证,以下是端点函数的定义:
async sendVoiceCall(req, res, next) {
try {
const validationSchema = Joi.object({
phoneNo: Joi.string().required(),
});
const { error } = validationSchema.validate(req.body);
if (error) {
console.log("Error occured.....");
return next(error);
}
const { phoneNo } = req.body;
const select =
"-connectionsCount -competitionsCount -winsCount -audienceCount -prizesGeneratedCount -blackDiamonds -createdAt -updatedAt";
const user = await User.findOne({ phoneNo: phoneNo }).select(select);
if (!user) {
throw new CustomErrorHandler(
404,
"User with the provided phone does not exists"
);
}
// generate the OTP and save that with its expiry in the dB
const otp = functions.generateOTP();
await User.findOneAndUpdate(
{ _id: user._id },
{
otp,
otpDateTime: moment().add(5, "minute"),
},
{ new: true }
);
const message = `Your OTP code is: ${otp}`;
await sendVoiceCall(phoneNo, message);
res.status(200);
res.json({ message: "Call has initiated successfully" });
} catch (error) {
return next(error);
}
},
这里的 sendVoice() 函数实际上是使用 AWS Pinpoint 服务向用户发送 OTP 调用。
我正在尝试使用开玩笑来测试这个函数,这是我到目前为止所做的:
// Import necessary modules and dependencies
import sendVoiceCall from "../../../../utils/sendVoiceCall";
import User from "../../../../model/user";
import functions from "../../../../utils/functions";
import Joi from "joi";
import UsersController from "../UsersController";
jest.mock("../../../../services/CustomErrorhandler");
jest.mock("../../../../model/user");
jest.mock("../../../../utils/functions");
jest.mock("../../../../utils/sendVoiceCall");
jest.mock("joi", () => ({
object: jest.fn((x) => x),
validate: jest.fn((x) => x),
string: jest.fn((x) => x),
}));
describe("sendVoiceCall", () => {
it("should initiate a voice call with a valid phone number", async () => {
// Mock request and response object
const req = {
body: {
phoneNo: "+923132290956",
},
};
const res = {
status: jest.fn((x) => x),
json: jest.fn((x) => x),
};
const next = jest.fn();
// Mock User.findOne to return a user
// Mock the findOne method and return a query builder object
User.findOne = jest.fn().mockReturnThis();
// Mock the select method on the query builder
User.findOne.mockReturnValueOnce({
select: jest.fn().mockResolvedValue({
_id: "user_id",
}),
});
// Mock functions.generateOTP to return a fixed OTP value
functions.generateOTP.mockReturnValue("123456");
await User.findOneAndUpdate.mockResolvedValue({
_id: "user_id",
});
// Mock the sendVoiceCall utility function
sendVoiceCall.mockResolvedValue("Call initiated successfully");
const schema = Joi.object({
key: Joi.string(),
});
const value = {
key: "3",
};
// Call the function
await UsersController.sendVoiceCall(req, res, next);
// Assertions
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toHaveBeenCalledWith({
message: "Call has initiated successfully",
});
});
it("should handle errors when initiating a voice call", async () => {
// Mock dependencies and request object
const req = {
body: {
phoneNo: "+1234567890", // Replace with a valid phone number
},
};
const res = {
status: jest.fn().mockReturnThis(),
json: jest.fn(),
};
const next = jest.fn();
// Mock validation schema to return no error
Joi.object().mockReturnValue({
validate: jest.fn().mockReturnValue({ error: null }),
});
// Mock User.findOne to return no user (user not found)
User.findOne.mockResolvedValue(null);
// Call the function
await sendVoiceCall(req, res, next);
// Assertions
expect(next).toHaveBeenCalledWith(
new CustomErrorHandler(404, "User with the provided phone does not exist")
);
});
it("should handle validation errors", async () => {
// Mock dependencies and request object
const req = {
body: {
phoneNo: "", // An empty phone number (invalid)
},
};
const res = {
status: jest.fn().mockReturnThis(),
json: jest.fn(),
};
const next = jest.fn();
// Mock validation schema to return an error
Joi.object().mockReturnValue({
validate: jest
.fn()
.mockReturnValue({ error: new Error("Validation error") }),
});
// Call the function
await sendVoiceCall(req, res, next);
// Assertions
expect(next).toHaveBeenCalledWith(new Error("Validation error"));
});
});
我已经尝试了三个测试用例,但是当我运行此测试文件时,我的所有测试用例都失败了,并出现以下错误:
✕ should initiate a voice call with a valid phone number (15 ms)
✕ should handle errors when initiating a voice call (2 ms)
✕ should handle validation errors (1 ms)
● sendVoiceCall › should initiate a voice call with a valid phone number
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: 200
Number of calls: 0
62 |
63 | // Assertions
> 64 | expect(res.status).toHaveBeenCalledWith(200);
| ^
65 | expect(res.json).toHaveBeenCalledWith({
66 | message: "Call has initiated successfully",
67 | });
● sendVoiceCall › should handle errors when initiating a voice call
TypeError: Cannot read properties of undefined (reading 'mockReturnValue')
82 |
83 | // Mock validation schema to return no error
> 84 | Joi.object().mockReturnValue({
| ^
85 | validate: jest.fn().mockReturnValue({ error: null }),
86 | });
● sendVoiceCall › should handle validation errors
TypeError: Cannot read properties of undefined (reading 'mockReturnValue')
112 |
113 | // Mock validation schema to return an error
> 114 | Joi.object().mockReturnValue({
| ^
115 | validate: jest
116 | .fn()
117 | .mockReturnValue({ error: new Error("Validation error") }),
Test Suites: 1 failed, 1 total
Tests: 3 failed, 3 total
Snapshots: 0 total
Time: 4.932 s, estimated 6 s
请告诉我如何使用 jest 为我的函数 sendVoiceCall 编写单元测试,包括 Joi 验证。
答: 暂无答案
上一个:我怎样才能解决这个JOI问题
评论