목록으로
Testing

Jest - TDD를 Jest로 직접 해보자 (4)

Dev Park
2/28/2023
30 views

서론

저번 게시글까지는 지역정보에 관련된 기능을 만들어왔다.
하지만 기능 테스트를 성공했을때만 테스트 했을 뿐 실패했을 때는 테스트하지 못하였다.
오늘은 데이터베이스가 실패했을때의 상황을 어떻게 테스트해야하는지를 알아보자.

1단계 : 기능 요구사항 및 스팩 작성

오늘 기능의 요구사항 및 스팩은 아래와 같다.

  1. 클라이언트로부터 county 값을 요청받으면 지역정보를 반환하는 'getCityInfo' 메소드에서 데이터베이스가 오류를 발생했을 때를 가정한다.

  2. createQueryBuilder 객체의 getRawMany 메소드에서 예외가 발생하게 한다.

  3. 'getCityInfo' 함수 호출 시 발생하는 에러가 'Database query error' 와 같은 에러 메세지인지 확인한다.

2단계 : 테스트 코드 작성

우선 저번에 작성한 코드를 가져와서 테스트 할 것이기때문에 3단계와 4단계는 스킵한다.

테스트 코드를 작성하기 위해서는 저번에 작성한 코드를 참고해보자.

typescript
1 async getCityInfo(localDto: LocalDto): Promise<localEntity[]> { 2 try { 3 const cityInfo = await this.localRepository 4 .createQueryBuilder() 5 .where('county IN (:county)', { county: localDto.county }) 6 .getRawMany<localEntity>(); 7 return cityInfo; 8 } catch (err) { 9 throw err; 10 } 11 }

위의 코드에서 getRawMany를 호출했을때 예외가 발생하도록 해야한다.
이를 생각하면서 Mocking 해보자.

typescript
1 it('should throw error when database error', async () => { 2 jest.spyOn(localRepository, 'createQueryBuilder').mockReturnValue({ 3 where: jest.fn().mockReturnThis(), 4 getRawMany: jest 5 .fn() 6 .mockRejectedValue(new Error('Database query error')), 7 } as unknown as SelectQueryBuilder<localEntity>); 8 });

우선 저번에 작성한 것처럼 createQueryBuilder 메소드를 Mock 한다.
그 객체의 where 과 getRawMany를 jest.fn 를 이용해 Mock 한다.
하지만 이번에는 getRawMany에서 'Database query error' 라는 에러를 throw 하도록 한다.

또한 이 에러메세지가 제대로 발생하는지 를 테스트하는 코드를 작성해야한다.

typescript
1await expect(service.getCityInfo({ county: 'Seoul' })).rejects.toThrow( 2 new Error('Database query error'), 3);

위의 코드는 'getCityInfo' 를 호출하고 그 매개변수로 { county : 'Seoul' } 객체를 가진다.
그리고 rejects.toThrow(new Error('Database query error')) 을 이용해 'getCityInfo' 에서 오류가 발생하는지 확인하고, 발생한 오류가 'Database query error' 인지 테스트한다.

위의 테스트 코드를 하나로 적으면 아래와 같다.

typescript
1 it('should throw error when database error', async () => { 2 jest.spyOn(localRepository, 'createQueryBuilder').mockReturnValue({ 3 where: jest.fn().mockReturnThis(), 4 getRawMany: jest 5 .fn() 6 .mockRejectedValue(new Error('Database query error')), 7 } as unknown as SelectQueryBuilder<localEntity>); 8 await expect(service.getCityInfo({ county: 'Seoul' })).rejects.toThrow( 9 new Error('Database query error'), 10 ); 11 });

3단계 ~ 4단계

이미 작성된 코드로 테스트를 진행하니 3단계, 4단계는 패스하겠다.

5단계 : 테스트 통과 확인

imageimage

테스트를 통과했다.

6단계 : 리팩토링

리팩토링할 부분을 찾지 못하였으니 6단계는 패스하겠다.

7단계 : 2~6 단계 반복

기능의 요구사항과 스팩을 만족했으니 7단계도 스킵하겠다.

마치며

오늘은 성공한 테스트뿐만 아니라 실패했을때 어떤 에러가 발생하는지 테스트를 해보았다.
이제 다음 게시글부터는 날씨 관련된 기능을 테스트해보며 만들어보자.