在 Apollo 服务器测试中使用 Jest 模拟 ESM 功能

问题描述 投票:0回答:1

我正在尝试使用 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
typescript graphql es6-modules apollo-server ts-jest
1个回答
0
投票

基于此问题,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!");
});
© www.soinside.com 2019 - 2024. All rights reserved.