【问题标题】:How to mock SQL Server connection pool using Jest?如何使用 Jest 模拟 SQL Server 连接池?
【发布时间】:2021-08-13 11:34:36
【问题描述】:

我正在尝试为使用 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();
  });
});

Sandbox

【问题讨论】:

    标签: javascript typescript jestjs mocking ts-jest


    【解决方案1】:

    您需要模拟链中每个函数的返回值。你可以使用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();
      });
    });
    

    【讨论】:

    • 感谢您的回复,但我认为这不能解决问题。 ConnectionPool 是在处理程序 pool = new sql.ConnectionPool(""); 中创建的...您在测试中创建的这个池对象似乎已过时
    • 那我觉得你需要mock sql.ConnectionPool("")来返回pool的mock版本
    【解决方案2】:

    您可以使用jest ES6 Class Mocks 模拟mssql 包。您可以通过以下方式实现:

    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。您应该看到测试通过了。

    【讨论】:

    • @Harry 没问题,祝您的测试实施顺利;)
    猜你喜欢
    • 2014-02-23
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-02
    相关资源
    最近更新 更多