[Jest] 테스트용 DB 연결 후, mocking했던 bcrypt.compare 함수 수정하기

초이지수·2023년 6월 19일
0

Nest.js

목록 보기
4/14
post-thumbnail

Jest로 테스트 코드를 작성하던 중
DB처리를 모킹하는 것이 아니라 실제 DB에 연결해서 테스트를 해보고 싶었다.

.env 파일을 이용해
development / test 환경을 분리 시켜주었고,
development 데이터베이스와 test 데이터베이스를 분리해서 각각 연결시켜주었다.

테스트 코드를 실제 DB에 연결하니 코드 수정이 필요했다.


이 글에 작성한 부분은
사용자가 로그인 시에 입력한 비밀번호틀렸다고 가정한다면 ?
UnauthorizedException이 잘 throw 되는지 확인하는 부분이다.
(비밀번호를 암호화하기 위해 bcrypt를 이용했다)


1. 테스트용 데이터 베이스에 연결하기 전, 모킹했던 코드

bcrypt.compare - mockImplementation

115번째 줄
테스트용 데이터베이스에 연결하기 전 bcypt를 모킹했던 방식이다.

mockImplementation 메서드는 Mock함수가 어떻게 동작해야 하는지 직접 지정할 수 있다.
mockImplementation을 이용해 jest.spyOn(bcypt, 'compare'에 대한 동작을 새로 정의해주었다.

password와 InvalidPassword가 일치하는지 비교해(문자열) 같으면 true, 다르면 false를 반환하도록 작성했었다.


1-1. 테스트용 데이터 베이스에 연결 후, 에러 발생

테스트용 데이터베이스와 연결하니, 이와 같이 에러가 발생했다.

실제 bcypt.compare은 비밀번호와 저장된 해시값을 비교해, 두 값이 일치하면 true를 일치하지 않으면 false를 반환한다. (promise로 반환한다)

문자열 형태로 모킹한 값을 비교하는 게 아니라 실제로 비밀번호와 저장된 해시값을 비교해야 테스트를 해야 테스트가 통과될 것 같았다.


2. 데이터베이스 연결 후 첫 번째 수정

bcrypt.compare - mockResolvedValue로 수정

mockResolvedValue메서드로 수정했다.

mockResolvedValue 메서드는 Mock함수가 Promise를 반환하고, 그 Promise가 특정 값으로 resolve되어야 하는 경우에 사용한다.

비밀번호가 틀렸다고 가정을 해야돼서 false 값을 주었더니,
boolean 형식의 인수는 never 형식의 매개 변수에 할당될 수 없다고 에러가 발생했다.


jest.spyOn(bcrypt, 'compare').mockResolvedValue(false)는
bcrypt.compare 함수를 스파이 하는 동시에 결과값을 항상 false로 만들고 싶어 작성한 코드였다.

bcrypt.compare은 실제로는 두 개의 인자(비밀번호, 해시된 비밀번호)를 받는 함수이다.

그런데,
mockResolvedValue(false)는 호출되면 항상 Promise.resolve(false)를 반환하는 함수를 생성하는 것이었다.
=> 어떤 인자를 받아도 항상 false만 resolve하는 Promise를 반환하는 것이다!!!!!!!!오마이갓 이건 내가 원한게 아니야


mockImplementation 메서드는 스파이하려는 함수의 원래 인자의 종류와 개수를 그대로 유지한다고 해서..
다시... mockImplementation을 사용해 수정하기로 한다...

bcrypt.compare 처럼 인자를 받는 함수를 mock하려는 경우에는 mockResolvedValue보다는 mockImplementation을 사용하는 것이 더 적절하다


3. 데이터베이스 연결 후 두 번째 수정

다시.. bcrypt.compare - mockImplementation

위와 같이 mockImplementation 메서드를 사용해 항상 false값이 나오도록 수정해주었다.


PASS!

profile
닫혀 있어서 벽인 줄 알고 있지만, 사실은 문이다.

0개의 댓글