본문 바로가기

TIL

[TIL] 2024-02-26 jest 이슈

오늘의 이슈

 

jest로 테스트 코드를 작성하던 중 오류가 발생했다.

import { describe, jest } from "@jest/globals";
import { UsersService } from "../../../src/services/users.service";
import bcrypt from "bcrypt";

jest.mock("bcrypt");

let mockusersRepository = {
  createUser: jest.fn(),
  findUniqueUser: jest.fn(),
};

let usersService = new UsersService(mockusersRepository);

describe("users service unit test", () => {
  beforeEach(() => {
    jest.resetAllMocks();
  });

  test("signUpUser Method", async () => {
    const params = {
      name: "이름",
      email: "이메일",
      password: "비밀번호",
      pwConfirm: "비밀번호",
      profileImg: null,
      role: "admin",
    };

    const result = {
      id: 1,
      classId: null,
      name: "이름",
      email: "이메일",
      password: "해쉬된 비밀번호",
      profileImg: null,
      role: "admin",
    };

    const hashedPassword = "해쉬된 비밀번호";

    mockusersRepository.createUser.mockReturnValue(result);

    bcrypt.hash.mockReturnValue(hashedPassword);

    await expect(async () => {
      await usersService.signUpUser({});
    }).rejects.toThrow("필수항목을 체크해주세요");

    const createUser = await usersService.signUpUser(params);

    expect(mockusersRepository.createUser).toHaveBeenCalledTimes(1);
    expect(mockusersRepository.createUser).toHaveBeenCalledWith({
      name: "이름",
      email: "이메일",
      password: hashedPassword,
      profileImg: null,
      role: "admin",
    });

    expect(createUser).toEqual({
      user: {
        name: result.name,
        email: result.email,
        profileImg: result.profileImg,
        role: result.role,
      },
    });
  });
});

 

 

처음에 동작하던 로직이 다시 실행 시켜보니 

위처럼 오류가 발생했다.

오류 내용을 찾아보니 현재 5번 줄에 작성 되어있는 

jest.mock("bcrypt"); 이 구문이 require를 사용할때 사용하는 모킹 방식인듯 했다.

 

import { jest } from "@jest/globals";
import { UsersService } from "../../../src/services/users.service";
import bcrypt from "bcrypt";

let mockBcrypt = {
  default: jest.fn(),
  hash: jest.fn(),
  compare: jest.fn(),
};

let mockusersRepository = {
  createUser: jest.fn(),
  findUniqueUser: jest.fn(),
};

let usersService = new UsersService(mockusersRepository);

describe("users service unit test", () => {
  beforeEach(() => {
    jest.resetAllMocks();
  });

  test("signUpUser Method", async () => {
    const params = {
      name: "이름",
      email: "이메일",
      password: "비밀번호",
      pwConfirm: "비밀번호",
      profileImg: null,
      role: "admin",
    };

    const result = {
      id: 1,
      classId: null,
      name: "이름",
      email: "이메일",
      password: "해쉬된 비밀번호",
      profileImg: null,
      role: "admin",
    };

    const hashedPassword = "해쉬된 비밀번호";

    mockusersRepository.createUser.mockReturnValue(result);

    mockBcrypt.hash.mockReturnValue(hashedPassword);

    await expect(async () => {
      await usersService.signUpUser({});
    }).rejects.toThrow("필수항목을 체크해주세요");

    const createUser = await usersService.signUpUser(params);

    expect(mockusersRepository.createUser).toHaveBeenCalledTimes(1);
    expect(mockusersRepository.createUser).toHaveBeenCalledWith({
      name: "이름",
      email: "이메일",
      password: expect.any(String), // password : hashedPassword
      profileImg: null,
      role: "admin",
    });

    expect(createUser).toEqual({
      user: {
        name: result.name,
        email: result.email,
        profileImg: result.profileImg,
        role: result.role,
      },
    });
  });
});

 

따라서 모킹 방식을 바꾸고 실행시켰더니 이해가 안가지만 이번엔 실제로 해쉬된 값이 비밀번호에 들어가 버렸다.

 

그래서 그냥 해쉬의 값을 의미가 없도록 

      password: expect.any(String),

 

password 에 문자열아무 문자열을 담았고 비교해서 성공테스트를 완료할 수 있었다.