Jest를 활용한 테스트 중, 자주 발생하는 실수
// Url.ts
export class Url {
constructor(private url: string) {
if (url.indexOf('.com') === -1) {
throw new InvalidUrlError();
}
}
public toString(): string {
return this.url;
}
}
// UrlIdTooShortError.ts
export class InvalidUrlError extends Error {
constructor() {
super(`Invalid URL Error`);
}
}
위와같이 클래스와 에러를 만들어서 사용할 때, 에러가 제대로 발생하는지 테스트 할 필요가 있다
이런 경우에 종종 아래와 같은 형식으로 코드를 작성하게 되는데,
// url.test.ts
describe('test', () => {
it('should return an instance of Url class', () => {
expect(new Url('naver.com')).toBeInstanceOf(Url);
});
it('should return an Error when string is not a valid url', () => {
expect(new Url('navercom')).toThrow(InvalidUrlError);
});
});
이렇게 작성 할 경우 테스트가 실패한다. 결과적으로는 아래와 같이 수정해주어야 한다.
describe('test', () => {
it('should return an instance of Url class', () => {
expect(new Url('naver.com')).toBeInstanceOf(Url);
});
it('should return an Error when string is not a valid url', () => {
expect(() => new Url('navercom')).toThrow(InvalidUrlError); // <----- this
});
});
생각해보면 이유는 참 간단하다.
jest는 expect 함수를 통해 우리가 기대하는 결과를 평가하게 된다.
그런데 첫번째 코드에서는
new Url('navercom')
위와같은 생성자가 바로 실행된 후 전달된다. 따라서 jest에서 평가를 하기 전에 이미 에러가 발생하고, 결과적으로 테스트가 실패하게 된다.
이와는 다르게 아래의 코드에서는
() => new Url('navercom')
아래와 같은 화살표 '함수'가 전달된다.
따라서 expect 함수가 내부에서 전달받은 파라미터를 실행 할 때 까지, Url 인스턴스의 생성은 유보되고, jest의 통제 하에 에러가 발생한다.
이후 정상적으로 toThrow 메소드를 통해 에러를 평가 할 수 있게 되고, 테스트에 통과하게 된다.
심각한 실수는 아니지만, 코딩중에 종종 놓치는 실수라서 정리 해 본다.