한 가지 문제가 발생하는데, 콜백을 호출하기 전에 fn.getName()
가 완료되자마자 테스트도 완료된다는 것이다.
이 문제를 해결하기 위해서, 빈 인수가 있는 함수에 테스트를 넣는 대신 done
이라는 단일 인수를 사용한다. 테스트를 마치기 전에 done
콜백이 호출될 때까지 기다린다.
const fn = {
getName: (callback) => {
const name = "Pooh";
setTimeout(() => {
callback(name);
}, 3000);
},
};
test("3초 후에 받아온 이름 Pooh", (done) => {
function callback(name) {
expect(name).toBe("Pooh");
done();
}
fn.getName(callback);
});
만약 done
을 호출하지 않으면 테스트가 실패하고 Timeout 발생한다. try..catch문을 활용하여 error message 출력한다.
const fn = {
getName: (callback) => {
const name = "Pooh";
setTimeout(() => {
throw new Error("server error");
}, 3000);
},
};
test("3초 후에 받아온 이름 Pooh", (done) => {
function callback(name) {
try {
expect(name).toBe("Pooh");
done();
} catch (error) {
done();
}
}
fn.getName(callback);
});
테스트에서 Promise를 반환하면 Jest는 해당 Promise가 resolve 될 때까지 기다린다. 만약 Promise가 rejected 되면 테스트는 실패한다.
만약 return을 생략하면 fn.getAge()
에서 반환된 Promise가 해결되고 then()
이 콜백을 실행할 기회를 갖기 전에 테스트가 완료된다.
const fn = {
getAge: () => {
const age = 23;
return new Promise((resolved, rejected) => {
setTimeout(() => {
resolved(age);
}, 3000);
});
},
};
test("3초 후에 받아온 나이 23", () => {
return fn.getAge().then((age) => {
expect(age).toBe(23);
});
});
.resolves
/ .rejects
matcherExpect문에서 .resolves
matcher와 .rejects
matcher를 사용할 수도 있다.
// .resolves
test("3초 후에 받아온 나이 23", () => {
return expect(fn.getAge()).resolves.toBe(23);
});
// .rejects
const fn = {
getAge: () => {
const age = 23;
return new Promise((resolved, rejected) => {
setTimeout(() => {
rejected("error");
}, 3000);
});
},
};
test("3초 후에 error 발생", () => {
return expect(fn.getAge()).rejects.toMatch("error");
});
test("3초 후에 받아온 나이 23", async () => {
const age = await fn.getAge();
expect(age).toBe(23);
});
.resolves
/ .rejects
matcherasync
와 await
를 .resolves
또는 .rejects
와 결합할 수 있다.
test("3초 후에 받아온 나이 23", async () => {
await expect(fn.getAge()).resolves.toBe(23);
});
참고문헌,
https://jestjs.io/docs/asynchronous,
[Youtube]Jest 강좌 - 코딩앙마,