jest - mock 함수

raejun·2022년 3월 29일
0

mock 함수 예제

function check(predicate, onSuccess, onFail) {
  if (predicate()) {
    onSuccess('yes');
  } else {
    onFail('no');
  }
}

module.exports = check;
  • predicate함수가 true면 onSuccess함수 실행
  • predicate함수가 false면 onFail함수 실행
const check = require('../check');

describe('check', () => {
  let onSuccess;
  let onFail;

  beforeEach(() => {
    onSuccess = jest.fn();
    onFail = jest.fn();
  });

  it('should call onSuccess when predicate is true', () => {
    check(() => true, onSuccess, onFail);

    // expect(onSuccess.mock.calls.length).toBe(1);
    expect(onSuccess).toHaveBeenCalledTimes(1);
    // expect(onSuccess.mock.calls[0][0]).toBe('yes');
    expect(onSuccess).toHaveBeenCalledWith('yes');
    // expect(onFail.mock.calls.length).toBe(0);
    expect(onFail).toHaveBeenCalledTimes(0);
  });

  it('should call onFail when predicate is false', () => {
    check(() => false, onSuccess, onFail);

    expect(onFail).toHaveBeenCalledTimes(1);
    expect(onFail).toHaveBeenCalledWith('no');
    expect(onSuccess).toHaveBeenCalledTimes(0);
  });
});
  • onSuccess함수와 onFail함수는 jest.fn() mock으로 구성(임의의 함수가 존재한다고 가정)
  • check의 첫번째 인자가 true일 때, onSuccess는 1번 실행 되어야 함(toHaveBeenCalledTimes(1))
  • check의 첫번째 인자가 true일 때, onSuccess는 yes인자와 함께 호출 되어야 함(toHaveBeenCalledWith('yes')

Mock을 이용한 사용자 로그인 테스트

// UserService 부분
class UserService {
  constructor(userClient) {
    this.userClient = userClient;
    this.isLogedIn = false;
  }

  login(id, password) {
    if (!this.isLogedIn) {
      //return fetch('http://example.com/login/id+password') //
      // .then((response) => response.json());
      return this.userClient
        .login(id, password) //
        .then((data) => (this.isLogedIn = true));
    }
  }
}

module.exports = UserService;
  • login매소드는 로그인이 되어 있지 않으면 userClient의 login으로 로그인을 한 뒤 isLogedIn을 true로 바꿈
  • 로그인이 되어 있으면 userClient의 login매소드 동작하지 않음
// UserClient 부분
class UserClient {
  login(id, password) {
    return fetch('http://example.com/login/id+password') //
      .then((response) => response.json());
  }
}

module.exports = UserClient;
// User_service 테스트 코드
const UserService = require("../user_service");
const UserClient = require("../user_client");

jest.mock("../user_client"); // 유저 서비스 부분에 객체를 mock으로 사용
describe("UserService", () => {
  // login함수를 mock으로 success를 리턴
  const login = jest.fn(async () => {
    return "success";
  });
  // mock 연결, UserClient객체 mock과 login함수 mock을 연결
  UserClient.mockImplementation(() => {
    return {
      login,
    };
  });
  let userService;

  beforeEach(() => {
    userService = new UserService(new UserClient());
  });

  it("비로그인 상태에서 첫번째 로그인", async () => {
    await userService.login("abc", "abc");
    expect(login.mock.calls.length).toBe(1);
  });

  it("첫번째 로그인 이후 두번째 로그인", async () => {
    await userService.login("123", "123");
    await userService.login("123", "123");
    expect(login.mock.calls.length).toBe(1);
  });
});
profile
정리노트

0개의 댓글