jest.mockImplementation()-콜백함수 Mocking


BACKEND
NESTJS

jest.mockImplementation()

jest.mockImplementation(fn)은 Jest에서 Mock 함수의 동작을 커스텀하게 정의하는 데 사용되는 메서드입니다. 즉, jest.fn()으로 생성한 Mock 함수가 호출될 때 어떤 로직을 실행할지 직접 지정할 수 있습니다.

const mockFunction = jest.fn().mockImplementation((name) => `Hello, ${name}!`);
console.log(mockFunction("John")); // "Hello, John!"
console.log(mockFunction("Jane")); // "Hello, Jane!"

위 간단한 예제를 설명하자면,

  • jest.fn()으로 Mock 함수를 만들고, mockImplementation()을 사용하여 동작을 정의합니다.

  • 함수가 호출될 때 전달된 name을 활용하여 "Hello, ${name}!"를 반환하도록 지정합니다.

그렇다면 실전 예제의 경우에 어떤 사용 케이스가 있는지 알아볼게요.

콜백 함수

특정 함수가 콜백함수를 실행하는 경우, mockImplementation()를 활용할 수 있습니다.

다음은 transaction을 중앙화하여 사용하기 위한 코드입니다.

runInTransaction메서드는 transaction을 실행할 콜백함수을 전달받아 실행하죠.

import { DataSource } from "typeorm";
import { TransactionManagerPort } from "../port/transaction-manager.port";

export class TypeormTransactionAdapter
  implements TransactionManagerPort
{
  constructor(private readonly dataSource: DataSource) {
    if (!this.dataSource) {
      throw new Error(
        "DataSource is not provided to TypeormTransactionAdapter!",
      );
    }
  }

  async runInTransaction<T>(
    fn: () => Promise<T>,
  ): Promise<T> {
    const qr = this.dataSource.createQueryRunner();
    await qr.connect();
    await qr.startTransaction();

    try {
      const result = await fn();

      await qr.commitTransaction();
      await qr.release();

      return result;
    } catch (e) {
      await qr.rollbackTransaction();
      await qr.release();
      throw e;
    }
  }
}

runInTransaction메서드를 Mocking하기 위해서는 다음과 같이 jest.fn()만으로는 Mocking 할 수 없습니다.


describe("UpdateTechUseCase", () => {

  let transactionManager: jest.Mocked<TransactionManagerPort>;



    transactionManager = {
      runInTransaction: jest
        .fn()

    };

runInTransaction은 콜백 함수를 실행해야하여 반환하여야하기 때문이죠.

따라서 이 경우에 mockImplementation을 통해 비동기 콜백함수를 실행하여 반환한다를 작성해주면 됩니다.


🅾️

  let transactionManager: jest.Mocked<TransactionManagerPort>;

  beforeEach(async () => {


    transactionManager = {
      runInTransaction: jest
        .fn()
        .mockImplementation(async (fn) => await fn()),
    };

위와 같이 콜백함수를 실행하는 메서드가 있다면 mockImplementation을 활용하면 되겠습니다.