Jest
모킹
- 테스팅을 할 때 실제 모듈을 사용할 수 없을 때 이용한다.
- 만약
jsonwebtoken 모듈을 이용할 경우 실제로 검증을 할 수 없기 때문에 이럴 때 사용한다.
jest.mock('jsonwebtoken');
import jwt from 'jsonwebtoken';
- 아래코드는 테스팅 하기 위한 미들웨어 함수이다.
const verifyToken = (req, res, next) => {
try{
req.decoded = jwt.verify(req.headers.authorization, process.env.JWT_SECRET);
return next();
}catch(error){
console.log(error) ;
if(error.name === 'TokenExpiredError'){
return res.status(419).json({
code : 419,
message : '토큰이 만료되었습니다.',
});
}
return res.status(401).json({
code: 401,
message : '유효하지 않은 토큰입니다',
})
}
}
- 테스트를 진행하기 위해 실제 토큰을 생성한다.
const res = {
status : jest.fn(() => res),
json : jest.fn(),
};
const next = jest.fn();
test('success for jwt.verfiy method', () => {
const token = jwt.sign({
id : '1',
nick : 'mun',
}, process.env.JWT_SECRET, {
expiresIn : '1m',
issuer: 'unn04012',
});
const req = {
headers : {
authorization : token
}
};
verifyToken(req, res, next);
expect(next).toBeCalledTimes(1);
});
- req, res, next 변수를 가짜 객체를 만들어 해당 테스트만 동작하게 만든다.
- req 객체에는 많은 속성들이 있지만 위 테스트 코드가 동작하기 위해서는
headers.authorization 속성만 존재하면 된다.
- 후에
verifyToken(req,res,next) 미들웨어를 실행 한 후 next() 함수가 실행이 됬는지 확인한다.
test('expired for jwt.verify method', () => {
const req = {
headers : {
authorization : expiredToken,
}
};
const error = {name : 'TokenExpiredError'};
**jwt.verify.mockImplementation(() => {
throw error;
});**
verifyToken(req, res, next);
expect(res.status).toBeCalledWith(419);
expect(res.json).toBeCalledWith({
code : 419,
message : '토큰이 만료되었습니다.',
})
});
- 위 코드는 토큰은 유효하지만 만료되었을 때 실행되는 테스트코드이다.
- 실제 실행코드 부분에서
try ..catch 구문에서 catch 부분, 즉 에러를 일으켜야 하기 떄문에 mockImplementation()함수로 error를 실행시키고 이름은 TokenExpiredError로 선언하였다.
- 만약 jwt.verify() 메서드가 Promise 객체였다면
Promise.reject(error) 구문으로 실행을 시켰다.
- 후에 res.json() 함수에서 해당 객체가 확인한다.
test('invalid jwt token', () => {
const req = {
headers : {
authorization : expiredToken,
}
};
const error = {name : 'TokenInvalid'};
jwt.verify.mockImplementation(() => {
throw error;
});
verifyToken(req, res, next);
expect(res.status).toBeCalledWith(401);
expect(res.json).toBeCalledWith({
code : 401,
message : '유효하지 않은 토큰입니다',
})
})
- 마지막 부분은 유효하지 않은 에러를 일으키는 테스팅 코드이다.
- 이번에는 error 속성에 아무 이름이나 넣어서 테스트를 진행했다.