Backend 언어/JS&TS

[jest] mocking 사용하기

민초부 2021. 4. 24. 15:18
반응형

 - jest의 장점 중에 하나인 모킹(mocking)에 대해 정리한다. 

 

  • mocking이란 : ' mock = 모조품 ' 뜻 그대로 받아드리면 된다. 즉 테스트하고자 하는 코드가 의존하는 function이나 class에 대해 모조품을 만들어 '일단' 돌아가게 하는 것이다.
    • 대표적인 예로 내가 테스트해야하는 코드 속에 전부 완료되고 나서 이메일을 발송해야하는 기능이 있다면? 
    • 테스트를 돌릴 때마다 이메일 발송하는 부분이 실행이 되어서 찐으로 이메일을 보내거나 이메일 발송에 문제가 있으면 내가 테스트 하고자 하는 부분과 상관없이 계속 테스트 결과는 Fail이 떨어질꺼
    • 그래서 이럴 때 email보내는 부분을 '모킹'한다~ 라고 함 
  • mocking 처리 : 함수를 개별적으로 모킹할 땐  jest.fn(), 모듈 덩어리도 모킹 처리를 할 땐 jest.mock()을 사용한다.
    • jest.mocking()은 import한 모듈 전체를 모킹처리하여 모듈 관련된 것을 실제로는 돌아가지 않는 가짜를 만든다. 안에 있는 모든  export된 함수는 jest.mock 선언이 된다.
    • jest.mock('${모킹할 JS파일 위치}')로 사용하며 코드 위치는 상관없다. (무조건 jest.mock함수 호출을 맨 위로 올려 먼저 실행하기 때문에)
  • 이렇게 모킹된 함수들은 몇번 호출이 됐는지 등을 테스트 해볼 수 있다. 
expect(sendSignUp).toBeCalledTimes(2);

 

 

 

 

jest.mock('../src/emailService.ts', () => ({
  sendSignUp: jest.fn(),
  changeProjectStatus: jest.fn(),
  sendCompleteMail: jest.fn(),
}));

그렇다면 이 코드가 의미하는 것은 그럼 무엇일까 

  • 이 코드가 왜 이런지를 이해하려면 이들 먼저 알아야한다.
  • 기본적으로 jest.mock('../src/emailService.ts')만 해도 안에서 export 로 선언된 함수들은 전부 mock처리가 된다.
  • emailService.ts가 있는 directory에 '__mocks__' 이라는 이름의 directory를 만들고 이 안에 emailService.ts를 만들면 구체적으로 어떤 가짜의 mock객체를 만들지 커스터마이징 할 수 있다. 
  • 그럼에도 불구하고 왜 저 sendSignUp, change~~, sendCompleteMail은 jest.fn()로 재 mock선언을 했을까?
    __mocks__ directory안에 있는 커스터마이징한 mock file에 해당 function들이 없기 때문이다. 커스터마이징한 파일 안에서 선언만 해주면 이렇게 해줄 필요 없지만 이전 개발하던 누군가가 이렇게 해서 뭐 이런 문법이 따로 존재하는 건줄 알았는데 그게 아니였다.
  • 근데 단순히 이 용도뿐만이 아니라 해당 파일에 없는 function을 사용하고 있고 일단 모킹을 해야한다면 이러한 방식으로 추가적으로 mocking 한 function을 넣어줄 수 있으니 이렇게 활용이 가능할 것 같은 생각 
반응형