// fn.js
const fn = {
getName:(callback) => {
const name = "mike";
setTimeout(()=> {
callback(name);
}, 3000)
}
}
module.exports = fn;
// fn.test.js
test("3초 후에 받아온 이름은 Mike", ()=> {
function callback(name) {
expect(name).toBe("mike");
}
fn.getName(callback);
})
위의 코드를 실행해보면 테스트를 통과한다. 겉으로 보기에는 문제가 없어 보이지만, 분명 setTimeout()을 실행하여 3초 후 어떠한 동작을 하는 기능을 하는 비동기 함수를 테스트하는데, 테스트 통과까지 걸리는 시간은 3초를 넘기지 않는다. 비동기 동작이 제대로 수행되지 않는다는 것이다.
Jest는 실행하다가 테스트 코드의 끝에 도달하면 그대로 종료한다.
callback이 실행되지 않고 그대로 끝나버려서 3초가 걸리지 않은 것이다.
이러한 현상을 해결하기 위해 done을 사용한다.
// fn.js
const fn = {
getName:(callback) => {
const name = "mike";
setTimeout(()=> {
callback(name);
}, 3000)
}
}
module.exports = fn;
// fn.test.js
const fn = require('./fn');
test("3초 후에 받아온 이름은 Mike", (done)=> {
function callback(name) {
expect(name).toBe("mike");
done();
}
fn.getName(callback);
})
위 코드를 실행하면 마찬가지로 테스트는 통과하게 되고, 테스트 시간도 3초 이상이 걸린다. 비동기 코드를 제대로 테스트 한 것이다.
Jest는 done()
이 호출되기 전 까지 코드를 종료하지 않고 기다리기 때문에 callback을 실행할 수 있다.
// fn.js
const fn = {
getAge:()=> {
const age = 30;
return new Promise((res, rej) => {
setTimeout(()=> {
res(age);
}, 3000);
})
}
}
// fn.test.js
const fn = require('./fn');
test("3초 후에 받아온 나이는 30", ()=> {
return fn.getAge().then(age => {
expect(age).toBe(30);
})
});
위 코드를 실행해보면 정확하게 테스트가 진행됨을 알 수 있다.
// fn.test.js
const fn = require('./fn');
test("3초 후에 받아온 나이는 30", ()=> {
return expect(fn.getAge()).resolves.toBe(30);
});
resolves()
를 통해서도 Promise를 사용하는 비동기 코드를 테스트 할 수 있다. 에러 상황을 테스트하기 위해서는 rejects()를 사용하면 된다.
// fn.test.js
const fn = require('./fn');
test("3초 후에 받아온 나이는 30", async ()=> {
const age = await fn.getAge();
expect(age).toBe(30);
});
자바스크립트에서 async/await을 사용하는 방법과 동일하게 사용하면 된다.