【问题标题】:How to mock prisma with jest-mock如何用 jest-mock 模拟棱镜
【发布时间】:2022-02-10 05:20:56
【问题描述】:

我使用 prisma 与我的数据库交互,我想使用 jest-mock 来模拟 findMany 调用。 https://jestjs.io/docs/jest-object#jestmockedtitem-t-deep--false

brands.test.ts

import { PrismaService } from "@services/mysql.service";
import { mocked } from "jest-mock";
import faker from "@faker-js/faker";
import { GetBrands } from "./brand";
jest.mock("@services/mysql.service");

/**
 * @group unit
 */

describe("Brand", () => {
    afterAll(async () => {});

    const mockedPrismaService = mocked(PrismaService, true);
    it("should get a list of brands", async () => {
        const mockedData = [
            {
                id: faker.datatype.uuid(),
                name: faker.datatype.string(),
                image: {
                    source: "some_source",
                    dtype: "some_dtype",
                },
            },
        ];

        //@ts-ignore - because of relational data mockedData.image
        mockedPrismaService.brand.findMany.mockResolvedValueOnce(mockedData);

        const [response, error] = await GetBrands();

        console.log(response, error);
    });
});

mysql.service.ts

import mysql from "mysql2/promise";
import { Config } from "@config";
import { PrismaClient, Prisma } from "@prisma/client";

export const MySQLEscape = mysql.escape;
export const MySQLPreparedStatement = mysql.format;

export const PrismaService = new PrismaClient({});
export const PrismaHelper = Prisma;

但是,当我运行此测试时,我收到以下错误。

TypeError: Cannot read properties of undefined (reading 'brand')

【问题讨论】:

  • 包含GetBrands 函数的实现可能很有用 - 它是否使用您的PrismaService 而不是构造一个新的PrismaClient()

标签: node.js typescript unit-testing jestjs prisma


【解决方案1】:

工厂模拟

一种选择是在模拟客户端时选择使用工厂方法。

jest.mock("@services/mysql.service", () => ({
    PrismaService: {
        brand: {
            findMany: jest.fn(() => { })
        }
    },
}));

然后在您的测试中,您可以模拟 findMany 函数以返回您的测试数据,然后调用正在测试的函数。

const mockedData = [...];
PrismaService.brand.findMany.mockResolvedValueOnce(mockedData);
const result = await GetBrands();

虽然有点麻烦,但是很管用。

请注意,在我的示例中,我实现了GetBrands,如下所示:

import { PrismaService } from "@services/mysql.service"

export const GetBrands = async () => {
    const data = await PrismaService.brand.findMany();
    return data;
}

你的例子

在您的示例中,您使用的是自动模拟,我对它不太熟悉,所以我不确定如何让它工作。

导致错误的原因似乎是您的PrismaService 在此处导入时未定义:

import { PrismaService } from "@services/mysql.service";

然后调用带有未定义参数的mocked函数返回未定义:

const mockedPrismaService = mocked(undefined, true); // returns undefined

最后,调用以下是引发错误的原因:

mockedPrismaService.brand.findMany.mockResolvedValueOnce(mockedData);
// TypeError: Cannot read properties of undefined (reading 'brand')

我原以为你会追求这样的东西,但这会引发错误:

jest.mock("@services/mysql.service", () => ({
    PrismaService: mocked(PrismaService, true)
}));
//    6 |
//    7 | jest.mock("@services/mysql.service", () => ({
//>   8 |     PrismaService: mocked(PrismaClient, true)
//      |                    ^
//    9 | }));

查看文档

可能值得查看Prismas documentation on unit testing,因为他们提出了几种截然不同的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-23
    • 2023-03-14
    • 1970-01-01
    • 2019-06-18
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多