我正在尝试使用 Jest 和 typescript 在 Apollo Server 4 中设置集成测试
在我的解析器代码中,我有一个函数 checkIfAuthorized,它验证用户是否具有特定访问权限。 我试图模拟这个函数并总是返回一个特定的值
我有一个文件夹 src/tests/integration 我的 Integration.spec.ts 看起来像这样
import {ApolloServer} from "@apollo/server";
import {readFileSync} from 'fs';
const typeDefs = readFileSync('./schema.graphql', {encoding: 'utf-8'});
import {resolvers} from "../../resolvers/resolvers.js";
import {jest} from "@jest/globals";
import {AuthService} from "../../utils/authorization";
jest.mock('../../utils/authorization');
describe('Your test suite description', () => {
let authorization: AuthService;
beforeEach(async () => {
console.log("In before each ")
authorization = new AuthService(
});
it('returns hello with the provided name', async () => {
const checkIfAuthorizedMock = jest.spyOn(authorization, 'checkIfAuthorized');
checkIfAuthorizedMock.mockResolvedValue(await Promise.resolve());
const testServer = new ApolloServer({
typeDefs,
resolvers,
});
const response = await testServer.executeOperation({
query: `
mutation addUser($userId: String!) {
addUser(
....
}
`,
variables: {
userId: "1234",
},
operationName: 'AddUser'
},);
console.log("Response " + JSON.stringify(response))
});
});
这根本不模拟 checkIfAuthorized 函数,当调用解析器时,它调用原始方法而不是模拟的方法。 我做错了什么?
我的 src/utils/authorization.ts
export class AuthService {
async checkIfAuthorized(context?: MyContext, userId?: string) {
...
}
我的 src/resolvers/resolver.ts
export const addUserResolver = async (_parent: any, args: { input: AddUser },
_context: MyContext
): Promise<User> => {
try {
await authorization. checkIfAuthorized(_context, args.input.userId)
return await some_func()
} catch (err) {
}
}
这是我的 tsconfig.json
{
"compilerOptions": {
"rootDirs": ["src"],
"outDir": "dist",
"lib": ["es2020"],
"target": "es2020",
"strict": true,
"module": "esnext",
"noErrorTruncation": true,
"preserveConstEnums": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"types": ["node", "jest"],
},
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node"
},
笑话配置
import type { JestConfigWithTsJest } from 'ts-jest'
const jestConfig: JestConfigWithTsJest = {
// [...]
extensionsToTreatAsEsm: ['.ts'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
transform: {
'^.+\\.tsx?$': [
'ts-jest',
{
useESM: true,
},
],
},
}
export default jestConfig
基于此问题,Jest 无法正确模拟 ES 模块。以下是适合您情况的可能解决方案:
import { jest } from "@jest/globals";
jest.unstable_mockModule("../../src/main/authorization", () => ({
AuthService: function () {
return {
checkIfAuthorized: jest.fn().mockResolvedValue("ok mock!" as never),
};
},
}));
const AuthService = (await import("../../src/main/authorization")).AuthService;
test("Auth", async () => {
const authService = new AuthService();
expect(await authService.checkIfAuthorized("test")).toBe("ok mock!");
});