Node.js

auth-middleware 테스트 코드 작성

auth-middleware는 http 서버를 실행하는 코드가 아니고 그 자체로 함수인 코드이다. 따라서 supertest는 필요없다.

auth-middleware는 인자로 req, res, next를 받는다.

 

 

auth-middleware 코드

const jwt = require("jsonwebtoken")
const Joi = require("joi")
const {Users} = require("../models")

require('dotenv').config();

const authorizationSchema = Joi.string().required()
module.exports = async (req, res, next) => {
    try {
        const Authorization = await authorizationSchema.validateAsync(
            req.cookies.authorization ? req.cookies.authorization : req.headers.authorization)
        const {userId} = jwt.verify(Authorization, process.env.SECRET_KEY);
        await Users.findByPk(userId)
            .then((user) => {
                res.locals.user = user['dataValues']
            })
        next()
    } catch (error) {
        console.log(`${req.method} ${req.baseUrl} : ${error.message}`);
        res.status(401).send(
            {errorMessage: "사용자 인증에 실패하였습니다."}
        )
    }
}

 

 

 

 

 

 

 

auth-middleware 테스트 코드

auth-middleware가 정상적으로 동작할 수 있도록 코드를 넣어주어야 한다.

위의 코드에서 req, res는 오브젝트임을 알 수 있다.

authMiddleware 코드에 {}로 감싸진 인자를 넣어준다.

 

const authMiddleware = require("./auth-middleware"); // 미들웨어를 불러오는 코드

jest.mock("../models"); // mocking을 이용한다.

const { User } = require("../models");

test("정상적인 토큰을 넣은 경우 User.findByPk가 실행된다.", () => {
    User.findByPk = jest.fn(); // jest에서 fn()은 따로 의미를 가지고 모킹했다고 알려주는 함수이다.

    authMiddleware({
        headers: {
            authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjk5LCJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.27uuQ34QFqdzibQrQSJ0OKyI4wqIXz6wVvJ1uSlcESQ",
        }, // headers는 오브젝트이다
    }, {
        status: () => ({ // status는 함수이다
            send: () => {}, // status를 실행하고 반환한 값에 또 send를 참조하게 함. send 또한 함수이다.
        }),
        locals: {}, // 공식문서에 따르면 locals는 빈 객체이다.
    });

    expect(User.findByPk).toHaveBeenCalledTimes(1); // toHaveBeenCalledTimes는 몇번 호출됐는지 확인
    expect(User.findByPk).toHaveBeenCalledWith(99); // 99라는 값을 입력받았는지 확인한다.
});

// 에러가 나는 경우 테스트하는 코드
test("변조된 토큰으로 요청한 경우 로그인 후 사용하세요 라는 에러 메세지가 뜬다.", () => {
    const mockedSend = jest.fn();

    authMiddleware({
        headers: {
            authorization: "Bearer ",
        },
    }, {
        status: () => ({
            send: mockedSend, // 원래 코드에서 send로 보내주는 값이 mockedSend에 들어오게 된다.
        }),
        locals: {},
    });

    expect(mockedSend).toHaveBeenCalledWith({ // 내가 모킹한 함수가 어떤 인자와 함께 넘어왔는지
        errorMessage: "로그인 후 사용하세요",
    });
});

res.headers, res.locals 에서 headers, locals 또한 오브젝트이므로 오브젝트 형태로 값을 넣어준다.

res.status에서  status는 함수이다.

toHaveBeenCalled는 내가 모킹한 함수가 한번이라도 실행됐는지 확인해주는 함수이다.

 

 

 

 

mock이란?

실제 객체를 만들어 사용하기에 시간, 비용 등의 Cost가 높거나 혹은 객체 서로간의 의존성이 강해 구현하기 힘들 경우 가짜 객체를 만들어 사용하는 방법이다.
위 코드의 경우 User.findByPk에서 Sequelize가 데이터베이스에 접근하므로 modelsmocking 해준다.

가짜 객체를 이용해서 의존성을 없애는게 소용없어 보이겠지만 jest에서는 mocking한 함수에 대해서 여러 검증을 할 수 있는 기능을 제공한다.

'Node.js' 카테고리의 다른 글

socket.io  (0) 2022.01.12
node.js의 동작 원리  (0) 2021.09.23
auth-middleware 테스트 코드 작성  (0) 2021.08.07
Sequelize bulkCreate  (0) 2021.07.27
Node 자동 재실행  (0) 2021.07.26
jest를 활용한 테스트 코드 작성  (0) 2021.07.20