jestjs - การจำลองด้วย Jest + Supertest ใน Typescript
ฉันกำลังเขียนกรณีทดสอบจำลองด้วย jest ใน typescript และพยายามจำลองการเรียก API ด้วย supertest แต่ไม่สามารถได้รับผลตอบกลับที่จำลองไว้ เนื่องจากฉันกำลังใช้ Axios ในฟังก์ชันล็อกอิน และแม้แต่ลองจำลองการเรียก Axios ก็ไม่สำเร็จ
นี่คือโค้ดของฉัน:
auth.controller.ts
import { AxiosService } from "helpers";
export class AuthController {
constructor() {
...
// Some logic is written here
this.init()
}
public init() {
// prepared an route for login
router.post('/api/auth/login', this.login);
}
login = async function (req: Request, res: Response): Promise<void> {
// Preparing config for axios call with some logic
...
// created a service for Axios call to some third party.
AxiosService.call(req, res, config, "login");
}
}
auth.test.ts
import { AuthController } from "../../modules/auth/auth.controller";
jest.mock("../../modules/auth/auth.controller");
beforeAll(async () => {
const auth = new AuthController();
mockLogin = jest.spyOn(auth, "login");
});
afterAll(async () => {
server.stop();
});
test("should give login response", async () => {
mockLogin.mockImplementation(() => {
return Promise.resolve({ Success: true, body: "Login" });
});
const response = await request(server.app)
.post("/api/auth/login")
.send(requestBody)
.expect(200);
response.body // Getting the server response instead of mocked one
})
ลองกับโค้ดนี้แล้วเช่นกัน แต่ก็ไม่สำเร็จที่นั่น :
jest.mock('../../modules/auth/auth.controller', () => {
return {
AuthController: jest.fn().mockImplementation(() => {
return {
login: jest.fn()
}
})
}
})
นี่คือลักษณะของคลาส AxiosService ของฉัน:
export class AxiosService {
public static async call(...):Promise<void> {
try {
const { data } = await axios(...);
res.status(200).json(data);
} catch(err) {
res.status(400).send(err);
}
}
}
พยายามจำลองเมธอดการเรียกของ AxiosService ด้วยบรรทัดต่อไปนี้ :
jest.mock('../../helpers/AxiosService', () => {
return jest.fn().mockImplementation(() => {
return { call: () => { return {success:true, data:'mock'}} }
})
})
อย่างไรก็ตาม หลังจากที่เลียนแบบการเรียกใช้งาน Axios แล้ว ฉันได้รับ Async callback ไม่ถูกเรียกใช้งานภายใน 10000 มิลลิวินาที (ซึ่งฉันกำหนด) ที่ระบุโดย jest.setTimeout
ใครก็ตามที่สามารถช่วยได้นั้นจะยอดเยี่ยมสำหรับฉัน เพราะฉันเป็นมือใหม่เกี่ยวกับแนวคิดการล้อเลียน ดังนั้นบางทีฉันอาจพลาดอะไรบางอย่างไป
ขอบคุณล่วงหน้า
คำตอบ #1
กลยุทธ์การทดสอบที่เหมาะสมคือทุกหน่วยที่ไม่ได้ทดสอบต้องถูกจำลอง
เกิดการหมดเวลาการรอเพราะ Supertest รอการตอบกลับจากเซิร์ฟเวอร์และไม่มีการตอบกลับในกรณีของ AxiosService ที่ถูกจำลอง ดังนั้นจึงจำเป็นต้องจำลองแบบนี้:
...
return { call: (req, res) => { res.status(200).json({success:true, data:'mock'}); }
ในกรณีนี้ การทดสอบสามารถทำได้ทั้งการจำลองคลาสคอนโทรลเลอร์ด้วยคลาสเซอร์วิสที่จำลองไว้ หรือทดสอบพวกมันร่วมกันโดยใช้ Axios ที่จำลองไว้ เนื่องจาก AuthController ไม่ได้ทำอะไรมากเอง (AuthController และ AxiosService เป็นการสร้างนามธรรมเหนือตัวจัดการ Express ง่ายๆ) มันสามารถเป็นได้:
jest.mock('axios', () => jest.fn()) // at top level
...
axios.mockResolvedValue({ data: ... });
const response = await request(server.app)
