基于Directus SDK与Vitest的函数测试方法求助
解决Directus SDK单元测试的Mock问题
第一步:修复空Token测试的前置问题
你第三个测试的核心问题是调用directusSDK("")会直接抛出URL错误,根本无法获取SDK实例去调用getQuestions。测试空Token场景时,必须先传入合法的URL(随便填一个有效格式的字符串即可,比如"http://mock-directus"),才能继续验证getQuestions的逻辑:
describe("given no token was provided", () => { test("an error is thrown", async () => { const sdk = directusSDK("http://mock-directus"); // 注意getQuestions是异步函数,要用rejects断言异步错误 await expect(sdk.getQuestions("")).rejects.toThrowError("token was faulty!"); }); });
第二步:Mock Directus SDK,避免真实请求
单元测试不需要连接真实的Directus服务器,直接Mock SDK的核心方法即可,比用MSW更简单高效。
1. Mock整个Directus SDK模块
在测试文件顶部添加Mock逻辑,模拟SDK的链式调用和返回值:
import { vi } from "vitest"; // Mock @directus/sdk的所有导出 vi.mock("@directus/sdk", () => { // 模拟request方法的成功返回 const mockRequest = vi.fn().mockResolvedValue([ { id: 1, question: "测试问题1" }, { id: 2, question: "测试问题2" } ]); const mockClient = { request: mockRequest, with: vi.fn().mockReturnThis() // 链式调用返回自身,模拟.with()的行为 }; return { createDirectus: vi.fn().mockReturnValue(mockClient), authentication: vi.fn(), rest: vi.fn(), withToken: vi.fn().mockReturnArg(1), // 返回传入的第二个参数,即readItems的配置 readItems: vi.fn() }; });
2. 测试getQuestions的正常流程
验证当URL和Token都有效时,函数能正确调用SDK并返回数据:
describe("given valid url and token", () => { test("returns questions data", async () => { const sdk = directusSDK("http://mock-directus"); const result = await sdk.getQuestions("valid-token"); expect(result).toEqual([ { id: 1, question: "测试问题1" }, { id: 2, question: "测试问题2" } ]); // 验证request方法被正确调用 const { createDirectus } = await import("@directus/sdk"); const mockClient = createDirectus.mock.results[0].value; expect(mockClient.request).toHaveBeenCalled(); }); });
3. 测试请求失败的场景
模拟Directus返回错误的情况,验证函数的错误处理逻辑:
test("handles request error gracefully", async () => { const { createDirectus } = await import("@directus/sdk"); const mockClient = createDirectus.mock.results[0].value; // 模拟请求失败 mockClient.request.mockRejectedValue(new Error("Directus server error")); const sdk = directusSDK("http://mock-directus"); const result = await sdk.getQuestions("valid-token"); // 因为函数内部catch了错误,所以返回undefined expect(result).toBeUndefined(); // 验证错误被打印(可选) const consoleSpy = vi.spyOn(console, "error").mockImplementation(); await sdk.getQuestions("valid-token"); expect(consoleSpy).toHaveBeenCalledWith(new Error("Directus server error")); consoleSpy.mockRestore(); });
补充:完善你的main.ts代码
注意你的directusSDK函数没有返回getQuestions方法,外部无法调用,必须补充返回逻辑:
function directusSDK(directusURL: string) { if (!directusURL) throw Error("url was faulty!"); const client = createDirectus(directusURL).with(authentication()).with(rest()); async function getQuestions(token: string) { try { if (!token) throw Error("token was faulty!"); const result = await client.request<Questions[]>( withToken(token, readItems('Questions', { fields: ['*'] })) ); return result; } catch (error: any) { console.error(error); } } // 暴露getQuestions方法 return { getQuestions }; } // 定义Questions类型 type Questions = { id: number; question: string; // 补充你的其他字段 };
内容的提问来源于stack exchange,提问作者angularNoob
相关产品推荐
相关产品推荐

