为什么我的笑话模拟实现作为 jest.mock() 的第二个参数工作,但在抽象到 __mocks__ 文件夹时出现错误?

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

我正在尝试模拟

mssql
库来 JEST 测试我的 typescript Nodejs Azure Functions (v3)。为此,我编写了以下测试文件:

import httpTrigger from "./index";
import {
    BindingDefinition,
    functionRunner,
    HttpBinding,
} from "stub-azure-function-context";
import { describe, expect, jest, test, beforeEach } from "@jest/globals";
import functionJSON from "./function.json";

const bindings = functionJSON.bindings as BindingDefinition[];

jest.mock("mssql", () => {
    let mockRecordset = [{
        ContactID: 123456,
        FirstName: "Test",
        EmailAddress: "[email protected]",
        Number: "123-456-7890",
        AzureID: "az1234",
        HideAmountOwed: false,
    }];
    
    const mockQuery = jest.fn(() => ({
        recordset: mockRecordset,
    }));
    const mockInput = jest.fn(() => ({
        query: mockQuery,
    }));
    const mockRequest = jest.fn(() => ({
        input: mockInput,
    }));
    
    return {
    ConnectionPool: jest.fn(() => ({
        connect: jest.fn(),
        request: mockRequest,
    })),
    NVarChar: jest.fn(),
}});

describe("GetContact", () => {
    test("returns status 400 when not provided with a contactID or azureID", async () => {
        const bindingData = {
            req: new HttpBinding({
                method: "GET",
            }),
        };
        const context = await functionRunner(
            httpTrigger,
            bindings,
            bindingData
        );

        expect(context.res.status).toBe(400);
    });
});

这似乎有效。但是,当我将其解压到 **

__mocks__
** 文件夹时,如下所示:

const mock = jest.fn().mockImplementation(() =>{
    let mockRecordset = [
        {
            ContactID: 123456,
            FirstName: "Test",
            EmailAddress: "[email protected]",
            Number: "123-456-7890",
            AzureID: "az1234",
            HideAmountOwed: false,
        },
    ];

    const mockQuery = jest.fn(() => ({
        recordset: mockRecordset,
    }));
    const mockInput = jest.fn(() => ({
        query: mockQuery,
    }));
    const mockRequest = jest.fn(() => ({
        input: mockInput,
    }));

    return {
        ConnectionPool: jest.fn(() => ({
            connect: jest.fn(),
            request: mockRequest,
        })),
        NVarChar: jest.fn(),
    };
});

export default mock;

并省略

jest.mock
的第二个参数,就像这样......

import httpTrigger from "./index";
import {
    BindingDefinition,
    functionRunner,
    HttpBinding,
} from "stub-azure-function-context";
import { describe, expect, jest, test, beforeEach } from "@jest/globals";
import functionJSON from "./function.json";

const bindings = functionJSON.bindings as BindingDefinition[];

jest.mock("mssql");

describe("GetContact", () => {
    test("returns status 400 when not provided with a contactID or azureID", async () => {
        const bindingData = {
            req: new HttpBinding({
                method: "GET",
            }),
        };
        const context = await functionRunner(
            httpTrigger,
            bindings,
            bindingData
        );

        expect(context.res.status).toBe(400);
    });
});

现在出现以下错误:

 FAIL  dist/GetContact/index.test.js
  ● Test suite failed to run

    TypeError: mssql_1.default.ConnectionPool is not a constructor

       5 | const useTestDb = process.env.USE_TEST_DB === 'true';
       6 |
    >  7 | const pool = new sql.ConnectionPool(useTestDb ? testConString : prodConString);
         |              ^
       8 | if (useTestDb) {
       9 |     console.log('!!! USING TEST DATABASE');
      10 | }

为什么突然导致它“不是构造函数”?如何正确地将 moduleFactory 参数转换为可以共享的 mocks 项目?

node.js sql-server typescript jestjs azure-functions
1个回答
0
投票

类型错误:mssql_1.default.ConnectionPool 不是构造函数

发生上述错误是因为您的代码中可能是在

ConnectionPool
文件中模拟
__mocks__/mssql.ts
构造函数的方式。

更新后的模拟实现和文件结构如下:

// __mocks__/mssql.ts

const mock = jest.fn().mockImplementation(() =>{
    let mockRecordset = [
        {
            ContactID: 123456,
            FirstName: "Test",
            EmailAddress: "[email protected]",
            Number: "123-456-7890",
            AzureID: "az1234",
            HideAmountOwed: false,
        },
    ];

    const mockQuery = jest.fn(() => ({
        recordset: mockRecordset,
    }));
    const mockInput = jest.fn(() => ({
        query: mockQuery,
    }));
    const mockRequest = jest.fn(() => ({
        input: mockInput,
    }));

    return {
        ConnectionPool: jest.fn(() => ({
            connect: jest.fn(),
            request: mockRequest,
        })),
        NVarChar: jest.fn(),
    };
});

export default mock;

问题仍然存在,因为当您的测试代码尝试使用

ConnectionPool
创建
new sql.ConnectionPool
的新实例时,它期望
ConnectionPool
是构造函数。

  • 要解决此问题,您需要导出一个设置
    mssql
    模块结构的对象,其中
    ConnectionPool
    是构造函数。这就像
    __mocks__/mssql.ts
    文件已完成。
© www.soinside.com 2019 - 2024. All rights reserved.