#javascript #typescript #jestjs #mocking #ts-jest
Вопрос:
Я пытаюсь написать модульный тест jest для функции, которая использует mssql
.
import * as sql from "mssql";
let pool: sql.ConnectionPool = null;
export async function handler() {
if (pool === null) {
try {
pool = new sql.ConnectionPool("");
await pool
.request()
.input("SomeInput", sql.NVarChar(255), "input")
.execute("SomeStoredProcedure");
} catch (err) {
console.error(err);
}
}
}
Каков был бы самый простой способ издеваться над методами sql и утверждать, что они были вызваны?
import { handler } from "../src/main";
describe("test handler", () => {
it("should succeed", async () => {
const requestFn = jest.fn();
const executeFn = jest.fn();
const inputFn = jest.fn();
// Mock mssql connection pool with above functions
// *????????*
await handler();
// Expect the functions have been called
expect(requestFn).toHaveBeenCalled();
expect(executeFn).toHaveBeenCalled();
expect(inputFn).toHaveBeenCalled();
});
});
Ответ №1:
Вы можете издеваться над mssql
пакетом, используя насмешки класса jest ES6. Вы можете достичь этого, используя:
const mockExecute = jest.fn();
const mockInput = jest.fn(() => ({ execute: mockExecute }));
const mockRequest = jest.fn(() => ({ input: mockInput }));
jest.mock('mssql', () => ({
ConnectionPool: jest.fn(() => ({
request: mockRequest
})),
NVarChar: jest.fn()
}));
Взгляните на проект Stackblitz и запустите jest
его в терминале. Вы должны видеть, что тесты проходят успешно.
Комментарии:
1. @Гарри Без проблем удачи в реализации ваших тестов 😉
Ответ №2:
Вам нужно имитировать возвращаемое значение каждой функции в цепочке. Вы можете сделать это с помощью jest.fn().mockImplementation(implementation)
Расширяя ваш пример, чтобы использовать это, дайте нам следующее
import { handler } from "../src/main";
let pool;
describe("test handler", () => {
it("should succeed", async () => {
const requestFn = jest.fn();
const executeFn = jest.fn();
const inputFn = jest.fn();
pool = {
request: requestFn,
execute: executeFn,
inputFn: inputFn,
};
requestFn.mockImplementation(() => pool);
executeFn.mockImplementation(() => pool);
inputFn.mockImplementation(() => pool);
await handler();
// Expect the functions have been called
expect(requestFn).toHaveBeenCalled();
expect(executeFn).toHaveBeenCalled();
expect(inputFn).toHaveBeenCalled();
});
});
Комментарии:
1. Спасибо за ответ, но я не думаю, что это решает проблему. Пул соединений создается в обработчике
pool = new sql.ConnectionPool("");
… этот объект пула, созданный вами в тесте, кажется устаревшим2. Тогда я думаю, что вам нужно поиздеваться
sql.ConnectionPool("")
, чтобы вернуть макет версииpool