Jest | Basics 1 (소개 / 설치 / 간단한 Test)
객체 인스턴스의 모든 속성을 재귀적으로 비교 (
"deep" equality
라고도 함)
.toBe
와 비슷하게 사용 가능
toEqual()
,toBe()
모두 통과
fn.test.js
const fn = require("./fn");
// toBe
test("2 더하기 3은 5야.", () => {
expect(fn.add(2, 3)).toBe(5);
});
// toEqual
test("2 더하기 3은 5야.", () => {
expect(fn.add(2, 3)).toEqual(5);
});
테스트
npm test
- •
.toStrictEqual(value)
2..toEqual()
사용
toBe()
사용 불가 이유
객체 or 배열은 재귀적으로 돌면서 값을 확인해야 하기 때문
toBe()
사용 시
실패
fn.js
이름과 나이를 입력받아서 User 객체 리턴
// 객체 제작 함수 추가
const fn = {
add: (num1, num2) => num1 + num2,
makeUser: (name, age) => ({ name, age }), // 👈
};
module.exports = fn;
실패 케이스 제작(fn.test.js
)
const fn = require("./fn");
test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
expect(fn.makeUser("Mike", 30)).toBe({ // 👈 toBe 사용
name: "Mike",
age: 31, // 👈 다르게 적음
});
});
test
npm test
결과
나이 부분이 다름
수정(fn.test.js
)
const fn = require("./fn");
test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
expect(fn.makeUser("Mike", 30)).toBe({
name: "Mike",
age: 30, // 👈 맞게 적음
});
});
test
npm test
결과
실패
toEqual()
사용 시
성공
fn.test.js
const fn = require("./fn");
test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
expect(fn.makeUser("Mike", 30)).toBe({ // 👈 toBe
name: "Mike",
age: 30,
});
});
test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
expect(fn.makeUser("Mike", 30)).toEqual({ // 👈 toEqual
name: "Mike",
age: 30,
});
});
test
npm test
결과
toBe()
→ 실패
toEqual()
→ 통과
권고
깊은 비교를 위해서 toBe()
→ toStrictEqual()
로 사용 추천
보다 엄격하게 test 진행
( 객체가 동일한 types & 구조를 가지고 있는지 테스트 )
undefined
속성이 있는 key가 확인됨
ex) {a: undefined, b: 2}
는 {b: 2}
와 불일치
Array sparseness
가 확인됨
ex) [, 1]
는 [undefined, 1]
과 불일치
객체 유형이 동일한지 확인됨
ex) a
와 b
필드가 있는 클래스 인스턴스는 a
와 b
필드가 있는 리터럴 객체와 같지 않다.
모두 통과
fn.test.js
const fn = require("./fn");
test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
expect(fn.makeUser("Mike", 30)).toEqual({
name: "Mike",
age: 30,
});
});
test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
expect(fn.makeUser("Mike", 30)).toStrictEqual({
name: "Mike",
age: 30,
});
});
결과
npm test
결과
모두 통과
toEqual()
→ 불통toStrictEqual()
→ 통과 (개발자의 의도와 일치)
객체 수정 (fn.js
)
const fn = {
add: (num1, num2) => num1 + num2,
makeUser: (name, age) => ({ name, age, gender: undefined }),
// 👆 gender 추가
};
module.exports = fn;
결과
npm test
결과
null
인지 확인
.toBe(null)
과 동일
but, 오류 msg가 좀 더 친절함. → .toBeNull()
사용 추천
예시
const fn = require("./fn");
test("null은 null이다.", () => {
expect(null).toBeNull();
});
undefined
인지 확인
undefined
이 아닌지 확인
.not.toBe(undefined)
사용 가능
but, 코드에서 직접 undefined
를 참조하지 않는 것이 좋다.
true
인지 판별
6 falsy values
(false
, 0
, ''
, null
, undefined
, NaN
)외 모두 truthy
false
인지 판별
// 통과
const fn = require("./fn");
test("0은 false 이다.", () => {
expect(fn.add(1, -1)).toBeFalsy();
});
// [불통] false 값을 기대했는데 "helloworld"를 받아서 (빈 문자열이 아님)
const fn = require("./fn");
test("helloworld는 false 일까요?", () => {
expect(fn.add("hello", "world")).toBeFalsy();
});
// [통과].toBeTruthy()로 수정
test("비어있지 않은 문자열은 true입니다.", () => { // 👈 설명 수정
expect(fn.add("hello", "world")).toBeTruthy(); // 👈
});
.toBeGreaterThan(number | bigint) // 초과(크다)
.toBeGreaterThanOrEqual(number | bigint) // 이상(크거나 같다)
.toBeLessThan(number | bigint) // 미만(작다)
.toBeLessThanOrEqual(number | bigint) // 이하(작거나 같다)
사용하는 경우 예시
사용자가 입력한 id의 길이 제한
업로드된 파일의 크기가 적당한지 판별
예시
fn.test.js
const fn = require("./fn");
test("ID는 10자 이하여야 합니다.", () => {
const id = "THE_BLACK_ORDER";
expect(id.length).toBeLessThanOrEqual(10);
});
결과
10보다 작거나 같아야 하는데 15자이기 때문에 실패함을 알려줌
수정 후, 통과
const fn = require("./fn");
test("ID는 10자 이하여야 합니다.", () => {
const id = "THE_BLACK"; // 👈
expect(id.length).toBeLessThanOrEqual(10);
});
.toBe
.toEqual
// 정확하게 비밀 번호 4자리를 받을 때
test("비밀번호 4자리", () => {
const pw = "1234";
expect(pw.length).toBe(4);
});
test("비밀번호 4자리", () => {
const pw = "1234";
expect(pw.length).toEqual(4);
});
.toBeCloseTo(number, numDigits?)
로 근사치(가까운 값)인지 판별
숫자 다룰 때 주의 사항
몇몇 프로그램들(+ JS
)은 소수점을 정확하게 계산 못함. → .toBeCloseTo
활용
예시
JS에서
0.1+0.2 ≠ 0.3
이다. →.toBeCloseTo
로 해결
fn.test.js
test("0.1 더하기 0.2 는 0.3 이다", () => {
expect(fn.add(0.1, 0.2)).toBe(0.3); // 👈 toBe
});
결과
0.3이 아닌 0.30000000000000004 이 나옴
해결 (.toBeCloseTo
)
// 통과
const fn = require("./fn");
test("0.1 더하기 0.2 는 0.3 이다", () => {
expect(fn.add(0.1, 0.2)).toBeCloseTo(0.3); // 👈 toBeCloseTo
});
문자열이 정규식과 일치하는지 확인
대소문자 구분 제거법
.toMatch(/문자/i)
예시
a
있는지 확인
// [실패] a 없기 때문
test("Hello world에 a라는 글자가 있나요?", () => {
expect("Hello world").toMatch(/a/);
});
H
있는지 확인
// [성공] H 있기 때문
test("Hello world에 a라는 글자가 있나요?", () => {
expect("Hello world").toMatch(/H/);
});
소문자(h
) 있는지 확인
// [실패] h 없기 때문
test("Hello world에 a라는 글자가 있나요?", () => {
expect("Hello world").toMatch(/h/);
});
대소문자 구분 없애기
// [성공] 대소문자 구분 없어져서 h 있음
test("Hello world에 a라는 글자가 있나요?", () => {
expect("Hello world").toMatch(/h/i);
});
배열에서 특정
item
이 있는지 확인
실패 케이스
// [실패]
test("userList에 Mike가 있나?", () => {
const user = "Mike";
const userList = ["Tom", "Jane", "Kai"]; // 👈 Mike 無
expect(userList).toContain(user);
});
수정
// [성공]
test("userList에 Mike가 있나?", () => {
const user = "Mike";
const userList = ["Tom", "Mike", "Kai"]; // 👈 Mike 有
expect(userList).toContain(user);
});
.toThrowError(error?)
코드를 함수로 래핑해야 함.
그렇지 않으면 오류가 잡히지 않고 assertion이 실패할 것.
사용 이유
특정 오류가 발생했는지 테스트하기 위해
인수 유형
정규 표현식
error message matches the pattern
string
error message includes the substring
error object
error message is equal to the message property of the object
error class
error object is instance of class
예외 발생시키는 함수 제작 (fn.js
)
const fn = {
add: (num1, num2) => num1 + num2,
makeUser: (name, age) => ({ name, age, gender: undefined }),
throwErr: () => { // 👈 이 함수 실행 시, 항상 예외 발생
throw new Error('xx')
}
};
테스트 (fn.test.js
)
// [패스]
const fn = require("./fn");
test("이거 에러 나나요?", () => {
expect(() => fn.throwErr()).toThrow();
});
/*
패스 이유:
- () => fn.throwErr()에서 에러가 발생 했고 toThrow를 썼기 때문에 패스 됨.
- 이 테스트 케이스는 어떤 내용이든 상관없이 예외 발생 시, 무조건 패스. */
특정 에러 확인 테스트 (fn.test.js
)
특정 에러(ex.
throw new Error('xx')
)가 발생 되는지 테스트 하려면toThrow
인수에 내용 전달하여 확인 가능
// [실패] "oo"가 나와야 되는데 에러 msg는 "xx"
test("이거 에러 나나요?", () => {
expect(() => fn.throwErr()).toThrow("oo"); // 👈
});
// [통과] 에러 msg 가 "xx"로 동일하게 나옴
test("이거 에러 나나요?", () => {
expect(() => fn.throwErr()).toThrow("xx"); // 👈
});
참고