제대로 테스트 되지 않음.
3초(3000ms) 이상 걸려야 하는데 바로 통과(1ms)되고 종료
3초 후에 이름을 알려주는 함수 작성 (fn.js
)
/*
getName 함수는 콜백 함수를 받아서 3초 후에 name을
콜백의 첫 번째 인수로 넘겨줌. */
const fn = {
add: (num1, num2) => num1 + num2,
getName: (callback) => { // 👈
const name = "Mike";
setTimeout(() => {
callback(name);
}, 3000);
},
};
module.exports = fn;
사용하는 코드 작성 (fn.test.js
)
/*
getName함수 호출하고 콜백 함수 전달.
콜백은 name을 받아서 테스트 진행. */
const fn = require("./fn");
test("3초 후에 받아온 이름은 Mike", () => {
function callback(name) {
expect(name).toBe("Mike");
}
fn.getName(callback);
});
테스트
npm test
결과 확인
테스트 하니, 바로 통과
실패하는 코드로 수정 (fn.test.js
)
const fn = require("./fn");
test("3초 후에 받아온 이름은 Mike", () => {
function callback(name) {
expect(name).toBe("Tom"); // 👈 Tom으로 수정
}
fn.getName(callback);
});
테스트(npm test
) 후, 결과 확인
아마 가장 많이 사용되는 비동기 패턴이 이렇게 콜백을 사용하는 방식일 것.
but, Jest는 실행이 끝에 도달하게 되면 그대로 끝남.
→ 그래서 예정되어 있던 콜백함수가 실행되지 않는 것.
fn.test.js
const fn = require("./fn");
test("3초 후에 받아온 이름은 Mike", () => {
function callback(name) {
expect(name).toBe("Tom");
}
fn.getName(callback); // 👈 기다리지 않고 그냥 여기서 그냥 끝내는 것.
});
해결 방법
test함수에 콜백 함수(ex. done
)를 전달
모두 제대로 테스트 됨.
콜백 함수가 호출되기 전까지 Jest는 test를 끝내지 않고 기다림.
콜백 함수(done
) 전달 (fn.test.js
)
const fn = require("./fn");
test("3초 후에 받아온 이름은 Mike", (done) => { // 👈
function callback(name) {
expect(name).toBe("Tom");
done(); // 👈 callback이 실행되고 여기에 done 호출
}
fn.getName(callback);
});
테스트(npm test
)
실패 (3초이상 걸림)
이유 정확히 알려줌
Tom을 기대했는데 Mike 나옴.
fn.test.js
의 test의 toBe
를 다시 Mike로 바꾸기
테스트(npm test
) 결과 확인
3초 정도가 걸리고 통과
테스트 실패할 것
fn.test.js
const fn = require("./fn");
test("3초 후에 받아온 이름은 Mike", (done) => {
function callback(name) {
expect(name).toBe("Mike");
// done(); // 👈
}
fn.getName(callback);
});
/*
- 결과:
한참 걸리다가 실패.
살펴 보면 Timeout임. 5초 동안 timeout이 있고 그동안 응답이 없으면 실패로 간주. */
try catch
문으로 감싸주기
try catch
문 사용 (fn.test.js
)
const fn = require("./fn");
test("3초 후에 받아온 이름은 Mike", (done) => {
function callback(name) {
try { // 👈
expect(name).toBe("Mike");
done();
} catch (error) { // 👈
done();
}
}
fn.getName(callback);
});
함수에서 에러를 발생 시킴 (fn.js
)
const fn = {
add: (num1, num2) => num1 + num2,
getName: (callback) => {
const name = "Mike";
setTimeout(() => {
throw new Error("서버 에러.."); // 👈
}, 3000);
},
};
module.exports = fn;
테스트(npm test
) 후, 결과 확인
에러 잘 찍힘
- 더 명확 & 간결
- 콜백 함수 안 넘겨도 됨 &
return
필요
콜백 함수 안 넘겨도 되는 이유
Promise
로 return
해주면 Jest
는 resolve
될 때까지 기다림.
함수 제작 (fn.js
)
나이를 받아오는 함수 제작 & 3초 후에
resolve
const fn = {
(...생략)
getAge: () => {
const age = 30;
return new Promise((res, rej)=>{
setTimeout(()=>{
res(age)
}, 3000)
})
}
};
module.exports = fn;
테스트 코드_return
無 (fn.test.js
)
문제 有
const fn = require("./fn");
test("3초 후에 받아온 나이는 30", () => {
fn.getAge().then((age) => { // 👈 return 無
expect(age).toBe(30);
});
});
테스트 결과
통과. 그러나 빠르게 결과가 나옴. → 이상함.
.toBe
의 숫자를 바꿔도 (.toBe(31)
) 통과
테스트 코드 문제 해결_return
추가 (fn.test.js
)
const fn = require("./fn");
test("3초 후에 받아온 나이는 30", () => {
return fn.getAge().then((age) => { // 👈
expect(age).toBe(31);
});
});
테스트 결과
3초가 걸림 & 31이라서 실패 → 제대로 동작함.
(return
없으면 아까처럼 그냥 종료)
.toBe(30);
수정 시
3초가 걸림 & 통과 → 제대로 동작함.
간단하게 작성하고 싶을 때
fn.test.js
const fn = require("./fn");
test("3초 후에 받아온 나이는 30", () => {
return expect(fn.getAge()).resolves.toBe(30); // 👈
});
// 테스트 결과: 통과
[불통]일 경우
fn.js
const fn = {
(...생략)
getAge: () => {
const age = 30;
return new Promise((res, rej) => {
setTimeout(() => {
rej("error"); // 👈 이 부분을 바꿔주면 됨
}, 3000);
});
},
};
module.exports = fn;
fn.test.js
const fn = require("./fn");
test("3초 후에 받아온 나이는 30", () => {
return expect(fn.getAge()).rejects.toBe(30); // 👈 rejects로 수정
});
// 테스트 결과: 실패 -> 제대로 동작
[통과]일 경우
에러인지 확인하기 위해서
toMatch('error')
로 수정
fn.test.js
const fn = require("./fn");
test("3초 후에 에러가 납니다.", () => { // 👈 설명 수정
return expect(fn.getAge()).rejects.toMatch("error"); // 👈
});
// 테스트 결과: 통과함. (3초 후, 에러 발생) -> 제대로 동작
async
,await
사용 방식과 동일.
함수 (fn.js
)
const fn = {
(...생략)
getAge: () => {
const age = 30;
return new Promise((res, rej) => {
setTimeout(() => {
res(age); // 👈
}, 3000);
});
},
};
module.exports = fn;
테스트 코드 (fn.test.js
)
const fn = require("./fn");
test("3초 후 나이 30", async () => {
const age = await fn.getAge();
expect(age).toBe(30);
});
// 테스트 결과: 통과 -> 제대로 동작
fn.test.js
의 숫자 바꿈. (.toBe(31);
)
테스트 후, 결과 확인
3초 걸림 & 실패
다시 성공케이스로 수정
30으로 수정 (.toBe(30);
)
테스트 후, 결과 확인
성공
return
대신await
fn.test.js
const fn = require("./fn");
test("3초 후 나이 30", async () => { // 👈 async
await expect(fn.getAge()).resolves.toBe(30); // 👈 await
});
// 테스트 결과: 통과 -> 제대로 동작
참고