Как имитировать пул подключений SQL Server с помощью Jest?

#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