我正在尝试模拟
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 项目?
类型错误: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
文件已完成。