기본적으로 Jest는 Matcher를 이용해서 다양한 방식으로 값을 테스트해볼 수 있다. Matcher를 사용하기 위해서는 Expect를 이용해서 먼저 대상을 잡아주어야 한다. 그 이후에 내부에 있는 여러 Matcher메소드를 이용해서 값을 테스트하게 된다. 다양한 Matcher이 있지만 몇가지만 먼저 살펴보고 이후에 추가적인 내용은 후술하도록 하겠다.
모든 matcher들은 앞에 not을 써줌으로서 해당 조건에 match되지 않는 상황을 예측할 수 있다.
test("test(0) 2+1 != 4", () => {
expect(2 + 1).not.toBe(4);
});
not하나만 써주면 일치되지 않는 조건을 찾아서 확인할 수 있다. !==
조건은 not을 붙여서 테스트한다는 것을 미리 알아두고 가자.
test("test(1) 2 + 2 = 4", () => {
expect(2 + 2).toBe(4);
});
전에 살펴봤던 toBe Matcher다. 여기에서 expect(2 + 2)
는 기대 객체라는 것을 리턴한다. 물론 당연하게도 얘는 Promise
나 후처리를 하는 객체가 아니기 때문에 후에 따로 처리를 해줄 필요는 없고, Matcher만 Chaining 해주면 된다. 이 코드에서 .toBe()는 Primitive Value Matcher
로 일반적인 원시자료형
의 값만을 테스트한다.
1)
toBeGreaterThan('expect')
: 대상값이 예측값보다 크다.
2)toBeGreaterThanOrEqual('expect')
: 대상값이 예측값보다 크거나 같다.
3)toBeLessThan('expect')
: 대상값이 예측값보다 작다.
4)toBeLessThanOrEqual('expect')
: 대상값이 예측값보다 작거나 같다.
5)toBeCloseTo('expect')
: (float 타입 한정) 값에 가깝다.
숫자값 관련해서 비교할 수 있는 추가 Matcher들이다. >, >=, <, <=
와 같은 연산들을 대신해준다.
물론 직접 값을 비교해서 확인할 수 있지만, matcher는 기본적으로 명시적으로 값의 변동을 확인하고, 개선 방향점을 찾기 위한 TDD 방법론의 일종이기 때문에 굳이 이렇게 길게 써야하나라고 생각할 것 1도 없다.
정규표현식을 사용해서 내부에 match되는 문자열이 있는지 확인하는 matcher다.
1. test('there is no I in team', () => {
expect('team').not.toMatch(/I/);
2. test('but there is a "stop" in Christoph', () => {
expect('Christoph').toMatch(/stop/);
첫번째 test form은 I
라는 문자가 전체 문자열 team
에 포함되어 있지 않은지 확인할 수 있다.
두번째 test form은 Christoph
라는 문자열에 stop
이 포함되어 있는지 확인할 수 있다.
const shoppingList = [
'Diapers',
'Cellphone',
'Jeans',
'Cap',
'Paper towels',
'Milk',
];
test('shopping list has milk on it', () => {
expect(shoppingList).toContain('milk');
expect(new Set(shoppingList)).toContain('milk');
});
다음과 같이 순회가능한 요소인 Array와 Set에 대해서 toContain()
을 사용하게되면, 내부 요소중에 대상값이 포함되어있는지 확인해볼 수 있다. 이는 완전히 동일한 값을 가지고 있는지 확인하는 것이 아니라 내부의 한 요소만 확인하는 용도로 사용된다.
test('object assignment', () => {
const data = {one: 1};
data['two'] = 2;
expect(data).toEqual({one: 1, two: 2});
});
이런 식으로 toEqual()
matcher를 사용하게되면 data 객체의 변화값을 테스트할 수 있다. 재귀적으로 값을 비교하기 때문에 depth가 깊더라도 비교하는 과정을 거쳐 정확한지 테스트 해볼 수 있다. toEqual
의 전달인자 값이 객체나 배열이라도 검증할 수 있다.
1) toBeNull()
2) toBeUndefined()
3) toBeDefined()
4) toBeTruthy()
5) toBeFalsy()
이렇게 다섯가지로 bool type, null, 혹은 defined state 값을 확인할 수 있다. 당연하게도 이미 예측값이 null, undefined, bool값으로 존재하기 때문에 따로 비교값 전달인자를 넣어주지 않아도 된다.
test('null check', () => {
const data = null;
expect(data).toBeNull();
}
다음과 같이 작성하게 되면, data는 null이기 때문에 테스트 통과 텍스트를 출력받을 수 있다. 이와 마찬가지로 null, undefined, defined, truthy, falsy값을 체크할 수 있다.
function useAdd() {
throw new Error( 'you can't use infinite number in parameters');
}
test('check infinite number use case:', () => {
expect(() => useAdd()).toThrow(); // 에러 출력 확인
expect(() => useAdd()).toThrow(Error);// 에러 출력 확인
expect(() => useAdd()).toThrow(''you can't use infinite number in parameters'); // 에러 메세지 확인
expect(() => useAdd()).toThrow(/infinite/); // 에러 메세지 포함된 문자열 확인
추가적으로 더 많은 matcher들이 있지만, Jest API 문서를 살펴보고 좀 더 정리해서 시리즈로 적어두어야 겠다. Mocha나 Chai에 대한 것들 코드스테이츠를 진행하면서 확인했지만 확인하지 못한게 너무 많아서 그 부분도 정리해두면 좋을 것 같다. 기본적으로 코드를 작성하다보면 (특히나 JS와 같은 고오오오급 언어로) 스스로 놓치는 타입이나 변수, 혹은 값이 너무 많은데 개발을 하면서 이런 틀을 만들어두고 할 수 있다는 점에서 굉장히 신박한 것 같다. TDD에 대한 개념이나 방법론에 대한 것들을 머릿속에 좀더 정리해두면 차후에 이런 과정을 할 때 이유도 모르고 테스트케이스를 작성하지 않고 능동적으로 해결 해나갈 수 있지 않을까 싶다. 그나저나 블로깅할 때마다 썸네일 이미지를 붙이지 않고 있는데 나중에 이걸 자동으로 만들어주는 웹같은 걸 만들어보며 재미있지 않을까 싶다.