๐11์ฅ ํค์๋๐
jest ํจํค์ง
์ ๋ ํ ์คํธ
ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง
ํตํฉ ํ ์คํธ
๋ถํ ํ ์คํธ
(9์ฅ์ NodeBird ์๋น์ค๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉ)
ํ ์คํธ๋ฅผ ์ํ jest ํจํค์ง ์ค์น npm i -D jest
package.json์ ๋ช ๋ น์ด ์ถ๊ฐ
"scripts": {
"start": "nodemon app",
"test": "jest"
},
middlewares/index.test.js ์ ํ
์คํธ ์ฝ๋ ์์ฑ ํ
npm test๋ก ํ
์คํธ ์คํ
์ค์ NodeBird์ ์ฝ๋๋ฅผ ํ
์คํธํด ๋ณด๊ธฐ
middlewares/index.js์ ์๋ isLoggedIn, isNotLoggedIn ํจ์๋ฅผ ํ
์คํธ
https://inpa.tistory.com/entry/JEST-%F0%9F%93%9A-%EB%AA%A8%ED%82%B9-mocking-jestfn-jestspyOn
controllers/user.test.js ํ์ผ
jest.mock('../models/user');
const User = require('../models/user');
const { follow } = require('./user');
describe('follow', () => {
const req = {
user: { id: 1 },
params: { id: 2 },
};
const res = {
status: jest.fn(() => res),
send: jest.fn(),
};
const next = jest.fn();
test('์ฌ์ฉ์๋ฅผ ์ฐพ์ ํ๋ก์์ ์ถ๊ฐํ๊ณ success๋ฅผ ์๋ตํด์ผ ํจ', async () => {
User.findOne.mockReturnValue({
addFollowing(id) {
return Promise.resolve(true);
}
});
await follow(req, res, next);
expect(res.send).toBeCalledWith('success');
});
test('์ฌ์ฉ์๋ฅผ ๋ชป ์ฐพ์ผ๋ฉด res.status(404).send(no user)๋ฅผ ํธ์ถํจ', async () => {
User.findOne.mockReturnValue(null);
await follow(req, res, next);
expect(res.status).toBeCalledWith(404);
expect(res.send).toBeCalledWith('no user');
});
test('DB์์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด next(error) ํธ์ถํจ', async () => {
const message = 'DB์๋ฌ';
User.findOne.mockReturnValue(Promise.reject(message));
await follow(req, res, next);
expect(next).toBeCalledWith(message);
});
});
์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ด์ฉ์ ๋ฑ๋กํ๋ ๊ฒ์ด ์๋๋ฏ๋ก ์ค์ ์๋น์ค์ ์ค์ DB์์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์.
์ ๋ ํ ์คํธ๋ก๋ ํ๊ณ๊ฐ ์์ => ํตํฉ ํ ์คํธ๋ ์์คํ ํ ์คํธ
package.json์ ๋ช
๋ น ์ถ๊ฐ
jest --coverage ์ต์
: jest๊ฐ ํ
์คํธ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๋ถ์
"scripts": {
"start": "nodemon app",
"test": "jest",
"coverage": "jest --coverage"
},
File: ํ์ผ๊ณผ ํด๋ ์ด๋ฆ
% Stmt: ๊ตฌ๋ฌธ ๋น์จ
% Branch: if๋ฌธ ๋ฑ์ ๋ถ๊ธฐ์ ๋น์จ
% Funcs: ํจ์ ๋น์จ
% Lines: ์ฝ๋ ์ค ์ ๋น์จ
Uncovered Lines #s: ์ปค๋ฒ๋์ง ์์ ์ค ์์น
models/user.test.js ์์ฑ
routes/auth.test.js ์์ฑ - ๋ก๊ทธ์ธ ๋ผ์ฐํฐ ํ ์คํธ
const request = require('supertest');
const { sequelize } = require('../models');
const app = require('../app');
beforeAll(async () => {
await sequelize.sync();
});
describe('POST /join', () => {
test('๋ก๊ทธ์ธ ์ ํ์ผ๋ฉด ๊ฐ์
', (done) => {
request(app)
.post('/auth/join')
.send({
email: 'zerohch0@gmail.com',
nick: 'zerocho',
password: 'nodejsbook',
})
.expect('Location', '/')
.expect(302, done);
});
});
describe('POST /join', () => {
const agent = request.agent(app);
beforeEach((done) => {
agent
.post('/auth/login')
.send({
email: 'zerohch0@gmail.com',
password: 'nodejsbook',
})
.end(done);
});
test('์ด๋ฏธ ๋ก๊ทธ์ธํ์ผ๋ฉด redirect /', (done) => {
const message = encodeURIComponent('๋ก๊ทธ์ธํ ์ํ์
๋๋ค.');
agent
.post('/auth/join')
.send({
email: 'zerohch0@gmail.com',
nick: 'zerocho',
password: 'nodejsbook',
})
.expect('Location', `/?error=${message}`)
.expect(302, done);
});
});
describe('POST /login', () => {
test('๊ฐ์
๋์ง ์์ ํ์', (done) => {
const message = encodeURIComponent('๊ฐ์
๋์ง ์์ ํ์์
๋๋ค.');
request(app)
.post('/auth/login')
.send({
email: 'zerohch1@gmail.com',
password: 'nodejsbook',
})
.expect('Location', `/?error=${message}`)
.expect(302, done);
});
test('๋ก๊ทธ์ธ ์ํ', (done) => {
request(app)
.post('/auth/login')
.send({
email: 'zerohch0@gmail.com',
password: 'nodejsbook',
})
.expect('Location', '/')
.expect(302, done);
});
test('๋น๋ฐ๋ฒํธ ํ๋ฆผ', (done) => {
const message = encodeURIComponent('๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค.');
request(app)
.post('/auth/login')
.send({
email: 'zerohch0@gmail.com',
password: 'wrong',
})
.expect('Location', `/?error=${message}`)
.expect(302, done);
});
});
describe('GET /logout', () => {
test('๋ก๊ทธ์ธ ๋์ด์์ง ์์ผ๋ฉด 403', (done) => {
request(app)
.get('/auth/logout')
.expect(403, done);
});
const agent = request.agent(app);
beforeEach((done) => {
agent
.post('/auth/login')
.send({
email: 'zerohch0@gmail.com',
password: 'nodejsbook',
})
.end(done);
});
test('๋ก๊ทธ์์ ์ํ', (done) => {
agent
.get('/auth/logout')
.expect('Location', `/`)
.expect(302, done);
});
});
//ํ
์คํธ ์ข
๋ฃ ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฆฌํ๋ ์ฝ๋ ์ถ๊ฐ
afterAll(async () => {
await sequelize.sync({ force: true });
});
[์ถ์ฒ] ์กฐํ์, ใNode.js ๊ต๊ณผ์ใ, ๊ธธ๋ฒ(2020), p521-560
๋น์นธ ์ฑ์ฐ๊ธฐ ๋ฌธ์ (๋น์นธ์ ๋๋๊ทธํด์ ์ ๋ต์ ๋งํ ๋ณด์ธ์!)
1. ํ ์คํธ ๊ณผ์ ์์ ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง๋ฅผ ๋ถ์ํ๋ ์ต์ ์ (jest --coverage)์ด๋ค.
2. ๋ชจํน์ ํตํด ์ค์ ๋ก ๋์ํด์ผ ํ๋ ๋ถ๋ถ ๋์ (๊ฐ์ง ๊ฐ์ฒด, ๊ฐ์ง ํจ์, ๊ฐ์ง ๋ชจ๋)๋ก ๋์ฒดํ ์ ์๋ค.
3. ํ ์คํธ๋ฅผ ์ํ ํจํค์ง๋ (jest), ํตํฉ ํ ์คํธ๋ฅผ ์ํ ํจํค์ง๋ (supertest), ๋ถํ ํ ์คํธ๋ฅผ ์ํ ํจํค์ง๋ก๋ (artillery)๋ฅผ ์ค์นํ๋ค.
4. ์ด ์ฅ์์ ์ ๋ ํ ์คํธ๋ (ํจ์) ๋จ์, ํตํฉ ํ ์คํธ๋ (๋ผ์ฐํฐ) ๋จ์์์ ์ํํด๋ณด์๋ค.
5. (OX ํด์ฆ) ํ ์คํธ ํ๊ฒฝ์์ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ฐ๋ก ๊ตฌ์ถํด์ผํ๋ค. (์ ๋ต: O )
[๋ ธ๋ 2] 15์ฅ. AWS๋ก ๋ฐฐํฌํ๊ธฐ (0) | 2024.01.12 |
---|---|
[๋ ธ๋ 2] 12์ฅ. ์น ์์ผ์ผ๋ก ์ค์๊ฐ ๋ฐ์ดํฐ ์ ์กํ๊ธฐ (0) | 2024.01.05 |
[๋ ธ๋ 2] 10์ฅ. ์น API ์๋ฒ ๋ง๋ค๊ธฐ (0) | 2023.12.22 |
[๋ ธ๋ 2] 9์ฅ. ์ต์คํ๋ ์ค๋ก SNS ์๋น์ค ๋ง๋ค๊ธฐ (1) | 2023.12.01 |
[๋ ธ๋ 2] 8์ฅ. MongoDB (0) | 2023.11.24 |