유용한 Matcher

2022-05-12

toBe같은 함수를 Matcher 라고 합니다.

toBe는 숫자나 문자 등의 기본 타입값을 비교할때 사용합니다.

객체나 배열 비교 : toEqual()

toBe와 비슷하게 사용할 수 있는 함수에 대하여 알아 보겠습니다.

test('2 더하기 3은 5야.', () => {
    expect(fn.add(3, 2)).toBe(5);
});

test('2 더하기 3은 5야.', () => {
    expect(fn.add(3, 2)).toEqual(5);
});

// 둘다 통과 하였습니다.
2 passed, 2total

함수를 추가해 보겠습니다.

const fn = {
    add: (num1, num2) => num1 + num2,
    makeUser: (name, age) => ({ name, age }),
};

module.exports = fn;

실패하는 테스트를 만들어보겠습니다.

test('이름과 나이를 전달받아서 객체를 반환해줘', () => {
    expect(fn.makeUser("Mike", 30)).toBe({
        name: "Mike",
        age: 31
    });
});

// 둘다 통과 하였습니다.
- "age" : 31,
+ "age" : 30,

나이 부분이 다르다고 친절하게 알려줍니다.

정상동작하는 테스트로 변경해 보겠습니다.

test('이름과 나이를 전달받아서 객체를 반환해줘', () => {
    expect(fn.makeUser("Mike", 30)).toBe({
        name: "Mike",
        age: 30
    });
});
// serializes to tho same string

하지만 실패하였습니다.

객체나 배열은 재귀적으로 돌면서 값을 확인 해야 하기 때문에, toEqual을 사용해야 합니다.

If it should pass with deep equality, replace "toBe" with "toStrictEqual"

깊은 비교를 위하여 toStrictEqual을 사용하라고 하고 있습니다.

toEqual을 사용해도 되는데, 두개 차이점을 알아보겠습니다.

더 엄격하게 체크 : toStrictEqual()

make 객체에 젠더를 추가해보겠습니다.

const fn = {
    add: (num1, num2) => num1 + num2,
    makeUser: (name, age) => ({ name, age, gender: undefined }),
};

module.exports = fn;

toEqual 은 통과가 되고, toStrictEqual 은 통과되지 못했습니다.

개발자 의도는 젠더라는 키가 undefined 이지만, 체크를 해야 되기 때문에 실패하는 것이 맞습니다.

때문에 권고하는데로, 더 엄격하게 체크를 하기 위하여

toStrictEqual을 사용하는 것이 좋습니다.

null, undefined, defined 판별 : toBeNull(), toBeUndefined(), toBeDefined()

이름그대로 null, undefined, defined 인 경우 통과됩니다.

test('null은 null 입니다.', () => {
    expect(null).toBeNull();
});

boolean 판별 : toBeTruthy(), toBeFalsy()

이건 boolean 값을 판별해줍니다.

true인지 false인지 판별해줍니다.

test('0은 false 입니다.', () => {
    expect(fn.add(1, -1)).toBeFalys();
});

// 통과 했습니다.

만약 아래와 같이 문자를 넣어준다면, helloworld라는 문자열이 생성되면서, true가 되기 떄문에 통과를 하지 못합니다.

test('비어있지 않은 문자열은 true 입니다.', () => {
    expect(fn.add("hello", "world")).toBeFalys();
});

// 통과하지 못했습니다.

toTruthy로 변경해준다면 통과할 것 입니다.

초과/이상/미만/이하 : toBeGreaterThan(), toBeGreaterThanOrEqual(), toBeLessThan(), toBeLessThanOrEqual()

숫자와 관련된 작업을 해보겠습니다.

숫자를 받아서 이상, 이하, 초과, 미만을 판단합니다.

입력한 문자열의 길이를 판단하거나, 업로드된 파일의 크기를 판단할때 사용해 볼 수 있습니다.

test('ID는 10자 이하여야 합니다.', () => {
    const id = "THE_BLACK_ORDER";
    expect(id.length).toBeLessThanOrEqual(10);
});

// 10보자 작거나 같아야 하나, 15이기 떄문에 실패했다고 알려줍니다.
FAIL

Expected: <= 10
Received:    15

아래와 같이 길이를 수정해 준다면

test('ID는 10자 이하여야 합니다.', () => {
    const id = "THE_BLACK";
    expect(id.length).toBeLessThanOrEqual(10);
});

// 통과하게 됩니다.
PASS

동일 : toBe(), toEqual()

정확하게 동일한 값을 테스트 한다면 어떻게 하면 될까요?

test('비밀번호 4자리', () => {
    const pw = "1234";
    expect(id.length).toBe(4);
});

test('비밀번호 4자리', () => {
    const pw = "1234";
    expect(id.length).toEqual(4);
});

PASS

위와 같이 toBe나 toEqual을 쓰면 됩니다.

소숫점 비교 : toBeCloseTo()

숫자를 다룰 때, 조심해야 할 것이 있습니다.

자바스크립트에서 0.1 + 0.2 = 0.3이 아닙니다.

test('0.1 더하기 0.2 는 0.3 입니다.', () => {
    expect(fn.add(0.1, 0.2)).toBe(0.3);
});

FAIL
Expected: 0.3
Received: 0.30000000000004

몇몇 프로그래밍 언어들은 소숫점에 대해서 정확하게 알지 못합니다.

자바스크립트도 마찬가지 입니다.

컴퓨터는 2진법을 사용하기 때문에 그렇습니다.

소수를 2진법으로 바꿧을때 값은 무한 소수가 되어버립니다.

그럼 테스트는 어떻게 하면 될까요?

toBe를 쓰지말고

toBeCloseTo를 사용하면 됩니다.

test('0.1 더하기 0.2 는 0.3 입니다.', () => {
    expect(fn.add(0.1, 0.2)).toBeCloseTo(0.3);
});

PASS

문자열 비교 : toMatch()

문자열과 관련된 작업 정규표현식과 toMatch를 이용해서 테스트를 진행해보겠습니다.

test('Hello World 에 a 라는 글자가 있나?', () => {
    expect('Hello World').toMatch(/a/);
});

FAIL
Expected: /a/
Received: "Hello World"

Hello World 에는 a라는 글이 없어서 실패하게 됩니다.

그럼 H로 바꾼다면 성공합니다.

test('Hello World 에 H 라는 글자가 있나?', () => {
    expect('Hello World').toMatch(/H/);
});

PASS

만약에 소문자 h로 바꾼다면 어떻게 될까요?

안됩니다.

test('Hello World 에 h 라는 글자가 있나?', () => {
    expect('Hello World').toMatch(/h/);
});

FAIL
Expected: /h/
Received: "Hello World"

대소문자 구분을 없애기 위해서는 뒷쪽에 i를 붙여주면 됩니다.

test('Hello World 에 h 라는 글자가 있나?', () => {
    expect('Hello World').toMatch(/h/i);
});

PASS

이 부분은 정규식을 모르시면 이해하기 어려우실수도 있습니다.

다만 toMatch로 문자열을 판단할 수 있구나 정도만 알고 넘어가셔도 됩니다.

배열 비교 : toContain

배열에서 특정 요소가 있는지 보려면 toContain을 사용하면 됩니다.

test('유저 리스트에 Mike가 있나?', () => {
    const user = "Mike";
    const userList = ["Tom", "Jane", "Kai"];
    expect('userList').toContain(user);
});

FAIL
Expected: "Mike"
Received: ["Tom", "Jane", "Kai"]

받은 배열에는 Mike가 없어서 실패 했습니다.

test('유저 리스트에 Mike가 있나?', () => {
    const user = "Mike";
    const userList = ["Tom", "Jane", "Kai", "Mike"];
    expect('userList').toContain(user);
});

PASS

Mike가 포함되어 있다면 위와 같이 성공하게 됩니다.

예외처리 : toThrow

어떤 함수를 실행했을때, 예외가 발생하는 경우는 toThrow 를 사용하면 됩니다.

아래와 같이 항상 예외를 발생시키는 함수를 만들어 보겠습니다.

const fn = {
    add: (num1, num2) => num1 + num2,
    makeUser: (name, age) => ({ name, age }),
    throwErr: () => {
        throw new Error("xx");
    },
};

module.exports = fn;
test('이거 에러 나나요?', () => {
    expect(throwErr()).toThrow();
});

PASS

위 코드는 에러가 발생했고, toThorw를 썻기 때문에 PASS가 되었습니다.

toThrow는 예외가 발생하기만 하면 통과를 하는데요,

만약 특정 에러인지 확인 하려면 인수에 내용을 전달할 수 있습니다.

test('이거 에러 나나요?', () => {
    expect(throwErr()).toThrow("oo");
});

FAIL
Expected: "oo"
Received: "xx"

oo가 나와야 되는데, xx가 나왔다고 FAIL이 떳습니다.

test('이거 에러 나나요?', () => {
    expect(throwErr()).toThrow("xx");
});

PASS

xx로 바꾸면 통과를 하게됩니다.

어떤작업을 했을때, 특정에러가 발생되는지를 테스트할 때 사용할 수 있습니다.

여기까지 많이 사용되는 Matcher에 대해서 알아보았구요,

이 외에도 다양한 Matcher들이 존재하며,

https://jestjs.io/docs/en/expect

위 페이지를 참고하시면 되고, 외우실 필요는 없습니다.

필요하실때 마다 들어와서 한번씩 읽어보시면 됩니다.

results matching ""

    No results matching ""

    99 other / uml

    04 react / JSX