항해 3기 4주차 WIL 2021.10.04~2021.10.11
2021.10.04
테스트코드를 작성하는중..
기본적으로 return이 확실하게 나오는 것들은 테스트코드 작성하는 것은 편해진 것 같다.
예를들면 이런 노가다같은 테스트코드..
하지만 아직 라우팅에 들어가는 함수들은 좀 많이 어렵다..
const { signupPost } = require('./signupPost');
const signupAuth = require('./signupValidation');
jest.mock('../../../models/user')
const users = require('../../../models/user');
let id = 'a1A'
let pw = 'b2B2'
let pwCheck = 'b2B2'
test('아이디, 비밀번호, 비밀번호 재확인을 입력하고 가입하기를 누르면 리스폰스를 보내준다.',async()=>{
const mockedSend = jest.fn();
const req = {
body:{
id:id,
pw,pw,
pwCheck:pwCheck,
}
}
const res = {
send:mockedSend,
}
const next = jest.fn();
await signupPost(req,res,next);
expect(mockedSend).toBeCalledWith({
result: 'success'
})
})
이부분에 있어서 오류가 나는데
이런 오류가 나면서 fail이 나온다..
오류가 나는 부분이 아마도 db에서 find 작업을 할때 이 부분이 뭔가 오류가 나는것 같은데 아직은 모르겠다..
오류를 해결했다. 본코드가 좋지않은 로직을 가지고 있는데,
애초에 find로 하면 배열로 결과값이 반환되어 빈 배열일경우 !isExist가 되지 않아서 이 부분을 findOne으로 해결했고, 찾아지지않을때는 null값이 반환되어 isExist.length가 실행되지 않는 경우가 있어서 이걸 빼버렸다.
exprts.signinPost = async (req, res, next) => {
const { id, pw } = req.body;
try {
let isExist = await users.find({ id, pw });
if (isExist.length) {
let accessToken = tokenController.generateAccessToken(id);
await res.cookie('login_token', accessToken, {
maxAge: 50 * 60 * 1000,
httpOnly: true,
});
res.send({ result: 'success' });
} else {
res.send({ result: 'Fail' });
}
} catch (err) {
next(err);
}
};
이게 본코드의 최종버전인데 원래 실행했던 본코드도 브라우저 상에서는 별 상관없이 동작이 잘 되었지만 테스트코드를 짜면서 약간 억지로 돌아가고 있던 것이 조금 더 매끄럽게 돌아가게 한 것 같아서 기분이 좋아졌다 ㅎ
튜터님이 오셔서 질문을 조금 했다.
리팩토링에 관한 질문에 대해 자세하게 답변해주셨는데 기억나는 것들은 요새는 controller와 router를 따로 나누지는 않는다고 한다. 이왕이면 service에서 비즈니스 로직과 관련된 친구들을 구성하고 나머지 함수들은 router에 놔둔다고했다.
긜고 테스트코드는 특정 기능에 대해서 문서처럼 볼 수 있도록 해서 테스트 코드의 경우의 수가 많지 않은 경우에는 직접 하난하나 치도록 하고 정말 많아서 for문을 써야 하는 경우에만 reduce와 snapshot을 이용해서 한다고 한다.
또한 공부할 키워드들을 많이 남겨주셨는데,
bdd, 엘라스틱 스택, 프로미스올, 프로미스레이스,
아마존에서 관계형 데이터를 쓰는 경우 rds
http 에러와 관련된 boom,
loggin 라이브러리인 윈스턴 등을 알려주셨다.
이것들은 나중에 내가 직접 공부해보고 적용시켜볼 것이다.
테스트코드에서 또 에러가 났다.
이번 문제는 비교적 알기 쉬운 문제지만 해결하는 방법을 몰라 애를 먹고있다. 중복확인을 위한 테스트코드였는데 기존 db에 접근을 하지 않고 mocking 된 db를 사용하고 있어 데이터가 없다보니 find했을 때 중복되는 값이 없는 것 같다.. 어떻게해결하지..?
2021.10.05
mocking된 method에서 값을 반환하고 싶을때 mockReturnValue method를 이용할 수 있었다.
첫번째 테스트 코드 (유저를 찾았을때 없으면 success가 반환되는 테스트)에서도 이걸 해줬다.
await users.findOne.mockReturnValue(null)
이 구문을 추가하여 가짜 반환값을 지정해줬다.
테스트코드를 이 이상 구현하기에는 내 실력이 아직 조금 부족한 것 같아 서버에 대한 이해도와 코드에 대한 이해도를 조금 더 늘려야 겠다는 생각을 가지고 나중에 다시 도전해보도록 해야겠다.
멘토님과의 대화를 통해 테스트코드를 짤때 db에 생성이나 삭제하는 영향이 가는 것들은 mock을 이용해서 하는 것이 조금 더 좋을 것 같고 조회같은 건 test db를 이용해서 하는 방법도 있다고 했다. 이부분은 조금 더 알아보고 그 전에 mysql로 현재 짜고있는 mongoose 코드를 바꾸는 작업을 해봐야 될 것 같다.
mysql을 설치하고 공부중.
연산자가 많다. 조건이 필요할 때 사용해보자.
git에 commit message를 convention으로 해야될 듯.
feat:새로운기능추가
fix:버그 수정
docs:문서 수정
style:코드 포맷팅, 세미콜론 누락, 코드변경이 없는 경우
refactor:코드 리팩토링
test:테스트 코드, 리팩토링 테스트 코드 추가
chore:빌드 업무 수정, 패키지 매니저 수정
제목은 50자 미만, 문장의 끝에 마침표 넣지 않음 과거 시제 사용하지 않고 명령어로 작성
제목 외에 추가적으로 정보를 전달하고 싶을 경우 본문에 추가 정보 기입
예시 : [feat] comment CRUD 기능 추가
2021.10.06
mysql 변환 작업중 query문을 변환해주는 sequelize 문법으로 find --> findAll, findOne 등으로 바꿔주고 찾는것도 다 where을 추가시켜 주는 등의 작업등을 했다. 하지만
이런 오류가 뜨는데 더 알아보겠다.
오타였다... type을 tpye으로 적어놨다..
그 후에는
이런오류가 떴다. associate하는 부분에서 잘못된 것 같다.
foreignKey로 할 수 있는 sourceKey는 primaryKey옵션을 true로 해야 할 수 있다고 하여 userId에 primaryKey:true를 주었더니 해결되었다.
이 부분에 있어서는 어차피 userId는 중복되지않고 아이디를 바꿀수는 없기 때문에 primaryKey로 주어도 상관 없을 것이라고 판단하여 true를 주었다. 그 후에 계속해서 테이블이 한개만 생성되는 현상이 있었는데 이것은 복붙을 하다보니 modelName과 tableName이 겹쳐서 계속해서 한개만 만들어 졌던 것이었다. 이부분은 user.js를 아예 주석처리를 해보고 실험 해본 결과에서도 user로 테이블이름이 정해져서 나오는 것을 보고 알아냈다!
그래도 오늘은 뿌듯하게 혼자서 많이 알아보고 한 것 같다.
자바스크립트에서
&&연산자(and)의 경우 앞의 값과 뒤에있는 값이 둘다 참스러울 경우 뒤의 값을 return해주고
거짓스러울경우 뒤의 값을 return해준다.
return consdition1 && condition2 && result
||연산자(or)의 경우 왼쪽의 값이 거짓스러우면 오른쪽에 있는걸 return함.
""||0||"Hi"||"t1" 일 경우 Hi가 반환
mongoose를 이용해서 쿼리를 하던걸 sequelize로 바꿨다.
2021.10.07
오늘은 공부가 참 안되는 날이다.
joi모듈을 이용해서 schema를 검증하는 작업을 위해서 joi파일을 만들고 벨리데이션을 했다.
const Joi = require('joi');
const joiSchema = {
Joi,
loginSchema: Joi.object({
userId: Joi.string().min(1).required(),
pw: Joi.string().min(1).required(),
}),
signupSchema: Joi.object({
userId: Joi.string()
.required()
.min(3)
.pattern(/^[a-zA-Z0-9가-힣]{3,}$/),
pw: Joi.string()
.required()
.min(4)
.pattern(/^[a-zA-Z0-9]{4,}$/),
pwCheck: Joi.ref('pw')
}),
commentSchema: Joi.object({
commentId: Joi.number().min(1),
cardId: Joi.number().min(1),
comment: Joi.string().required(),
commentDepth: Joi.number().default(0),
}),
cardSchema: Joi.object({
title: Joi.string().min(1).required(),
desc: Joi.string().min(1).required(),
pw: Joi.string().min(1).required(),
}),
likeSchema: Joi.object({
cardId: Joi.string().min(1).required(),
}),
};
module.exports = joiSchema;
조이에도 ref를 해서 똑같은 벨리데이션을 하는 작업을 할 수 있다는 것을 알았다.
2021.10.08
오늘은 공부대신 아직 숙제를 못하신분들의 오류 수정및 가이드를 조금 해드리고 내 공부는 mysql 쿼리문을 조금 배우고 알고리즘 문제를 조금 풀었다.
문제 설명
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.
let participant = ['leo', 'kiki', 'eden'];
let completion = ['eden', 'kiki'];
function solution(participant, completion) {
const hashMap = new Map();
// console.log(hashMap)
participant.forEach( p => {
const isExist = hashMap.get(p) //p값이 있는지 확인함
// console.log(isExist);
if ( !isExist ) { //없으면
hashMap.set(p,1) // key값으로 p를, value값으로 1을 줌
// console.log(hashMap)
return
}
hashMap.set(p,isExist+1) //있으면 value값 +1
})
for ( const c of completion ) {
const pNum = hashMap.get(c);//c값이 있는지 확인
// console.log(pNum);
hashMap.set(c,pNum-1); //c값이 hashMap에 있으면 value를 -1
// console.log(hashMap);
}
for ( const [ key, value ] of hashMap ) { //hashMap의 키,밸류값을 for문으로 돌림
if ( value !== 0 ) { //겹치지 않으면 value가 1이 될것임
return key //겹치지 않는값 출력
}
}
}
console.log(solution(participant,completion));
2021.10.09
오늘자는 TIL로 따로 작성했으니 참고 부탁드립니다!
20201.10.09-TIL
Author And Source
이 문제에 관하여(항해 3기 4주차 WIL 2021.10.04~2021.10.11), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@changchanghwang/항해-3기-4주차-WIL-2021.10.042021.10.11저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)