게시글
질문&답변
ProjectSkill은 데이터가 안들어가고 있습니다.
아 제가 cascade 옵션을 안 넣어줬던거군요. 덕분에 해결되었어요!답변 감사드립니다.
- 1
- 2
- 334
질문&답변
2.6버전 이상만 있을때 어떻게 진행하나요
Netflix Zuul - 프로젝트 생성 강의 영상 스크롤 내리시면 github 주소 있는데 이거로 실습하라고 나와 있네요.
- 1
- 1
- 1.2K
질문&답변
완강 하였습니다. CI CD는
네이버 카페에 문의하시면 지식공유자 답변을 받으실 수 있으실 거에요https://cafe.naver.com/metacoding?iframe_url=/MyCafeIntro.nhn%3Fclubid=30585956
- 0
- 3
- 474
질문&답변
3-6 ppk 파일 열기
바뀐 Putty 버전에서는 Auth 폴더에 +버튼을 누르면 Credentials가 있습니다. 그걸 누르면 ppk를 넣을 수 있는 곳이 있습니다.
- 0
- 2
- 547
질문&답변
Actuator dependency and Swagger Stater 3.0.0 충돌 에러 해결
공유 감사합니다. 덕분에 해결했네요!
- 1
- 2
- 749
질문&답변
회원도메인 개발 강의 내용중에서 enum
데이터 중에는 몇 가지 한정된 값을 갖는 것이 있죠. 가령, 계절의 경우, 봄, 여름 , 가을, 겨울요일은 월화수목금토일이와 같이 한정된 값을 갖는 타입을 자바에서는 Enum(열거 타입)이라고 합니다.Enum을 쓰면 지정된 값만 들어올 수 있기 때문에 이상한 값들을 걸러줄 수 있습니다.또한, 가독성이 좋은 코드를 작성할 수 있는데요.if (member.getGrade() == Grade.VIP) {...}이 코드를 보면 회원등급이 VIP인 경우 중괄호 블록을 실행한다는 것을 단번에 알 수 있겠죠?그래서 Enum타입을 씁니다.
- 1
- 2
- 751
질문&답변
hashmap사용시 항상 map으로 선언하시나요?
다형성을 활용하는 것인데요. 인터페이스로 조작하면 하위 클래스의 소스코드를 몰라도 상위 클래스 사용법만 알면 활용할 수 있습니다. 하위 클래스를 언제든 갈아 끼울 수 있고요. 말씀해주신 대로 구현체의 자체 기능은 바로 사용할 수는 없지만, Downcasting을 사용해서 하위 클래스의 자체 기능을 사용할 수 있습니다.((HashMap)map).clone(); 뭐 이런 식으로 사용하면 된다는 겁니다.
- 2
- 1
- 1K
질문&답변
junit.jupiter의 Assertions 질문
jupiter 말고 바로 위에있는 assertj.core를 사용하세요강의에도 나와 있는 것처럼, 체인 형식으로 사용할 수 있습니다. 스태틱 임포트 사용하는 거 추천하고요.
- 0
- 1
- 328
질문&답변
진행중에 jpa 오류가 발생 합니다.
에러 메세지를 보면 detached entity passed to persistJPA의 영속성 컨텐스트에서 분리된 상태라 예외가 발생한듯 보입니다. 강사님께서 제공한 코드 그대로 두시고CustomUserDetailsService의 loadUserByUsername()메소드 위에 @Transactional만 붙여도 정상 작동합니다. 설명을 덧붙이자면 영속성 컨텍스트는 트랜잭션 안에서 동작 해야 합니다.
- 0
- 2
- 685
질문&답변
P6spy의 가독성(?)이 이상합니다
개인적으로 p6spy보다는 application.properties(또는 application.yml) 설정에서 logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE이 한 줄 넣어주는게 더 깔끔한 것 같더라고요.디펜던시 추가해줄 필요도 없어서 간편하기 까지합니다.참고로 3.x버전에서 해보진 않았고 2.x에서 하는걸 추천합니다.
- 1
- 1
- 659
블로그
전체 42024. 10. 24.
0
[인프런 워밍업 클럽 스터디 2기 백엔드] 4주차 발자국
개요4주차 종료!Practical Testing 실용적인 테스팅 가이드를 완강 했다!인프런 워밍업 클럽 스터디 2기 백엔드 과정... 이것으로 끝!감격스럽다.4주차 공부한 내용권장 진도표에 맞게 진도를 나갔네? 배운 것들1. MockitoMockito 라이브러리를 써봤지만, 사용할 때마다 찝찝한 느낌을 갖고 사용해왔다.이번 주차에 강의를 학습하며 Mockito를 언제 쓰면 좋은지 @MockBean 과 @Mock 의 차이는 무엇인지를 제대로 알 수 있었다. 2. Classicist vs Mockist우빈님은 Classicist 인데, 강의를 들어보니 나도 Classicist가 되었다.정답이 있는 문제는 아니라 상황에 맞게 적절히 Mocking 할 땐 하고, 통합 테스트할 땐 하고 하면 될 듯 하다. 3. Test Fixture 가이드라인다른 강의에서 Fixture를 하나의 클래스로 관리하라고 배웠었다.그래서 그렇게 사용해왔는데, 문제는 원하는 필드를 지정해주고 싶을 때마다 Fixture를 생성하는 메서드가 증가하게 되고,메서드가 증가하면 관리가 너무 어려워지곤 했다. 더군다나 큰 프로젝트 같은 경우 엔티티당 필드가 수 십개가 넘어가는 게 대부분 인데, 이걸 전부 하나의 클래스로 관리하는 건 별로 좋은 방법 같지는 않다. 강의를 통해서 Test Fixture를 어떻게 생성하는 지, 어떻게 생성 메서드를 관리하는 지 배울 수 있었다. 4. 테스트 환경 통합하기테스트 환경을 통합해야 한다는 개념 자체를 몰랐다. 이런 게 가능할 거라 생각도 못했던 것 같다. 강의 들으면서 조금 충격을 받았다. 5. private 메서드를 테스트하고 싶은가? 그러면 책임 분리를 고민해봐라이것도 충격! private 메서드를 테스트하지 말라고 하시는 말씀에"그렇구나, 테스트 안 해도 되네? 개꿀!" 이렇게 생각하며 설렁설렁 듣고 있었는데,private 메서드를 새로운 객체에 public 메서드로 빼놓고 객체간 협력하게 하는 코드를 작성하시는 모습이 인상적이었다.테스트 생각을 많이 하다 보면 자연스레 객체지향에 가까워질 수도 있음을 깨달았다. 6. 학습테스트프로젝트에 쓰고 싶은 새로운 라이브러리를 테스트로 학습하는 건 정말 좋은 방법인 것 같다. 7. Spring REST docsSwagger만 사용해봤는데 Spring REST docs는 들어는 봤지, 이번에 처음 사용해봤다.설정하는 게 어렵긴 한데, 실무에서 많이 쓰인다고 하니 이번에 경험해볼 수 있어서 좋았다. 미션이번 주차에는 Day 15. 미션, Day 18. 미션이 있었다. Day 15. 미션 - Layered Test 작성법 자기만의 언어로 정리하기배운 내용을 다시 한 번 정리하는 거라 어렵진 않았다.https://zircon-neptune-a7d.notion.site/Day-15-Layered-test-124ba1f1340980ddb599f68747a2ddfe?pvs=4 Day 18. 미션 Day 18. 미션 - 1. @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks의 차이 정리하기역시 배운 내용을 다시 한 번 정리하는 거라 어렵진 않았다.https://zircon-neptune-a7d.notion.site/Day-18-129ba1f134098015983ade0586420ed1?pvs=4 Day 18. 미션 - 2. 수도 코드로 작성된 테스트 3개의 코드를 재배치하기제시된 수도 코드@BeforeEach void setUp() { ❓ } @DisplayName("사용자가 댓글을 작성할 수 있다.") @Test void writeComment() { 1-1. 사용자 생성에 필요한 내용 준비 1-2. 사용자 생성 1-3. 게시물 생성에 필요한 내용 준비 1-4. 게시물 생성 1-5. 댓글 생성에 필요한 내용 준비 1-6. 댓글 생성 // given ❓ // when ❓ // then 검증 } @DisplayName("사용자가 댓글을 수정할 수 있다.") @Test void updateComment() { 2-1. 사용자 생성에 필요한 내용 준비 2-2. 사용자 생성 2-3. 게시물 생성에 필요한 내용 준비 2-4. 게시물 생성 2-5. 댓글 생성에 필요한 내용 준비 2-6. 댓글 생성 2-7. 댓글 수정 // given ❓ // when ❓ // then 검증 } @DisplayName("자신이 작성한 댓글이 아니면 수정할 수 없다.") @Test void cannotUpdateCommentWhenUserIsNotWriter() { 3-1. 사용자1 생성에 필요한 내용 준비 3-2. 사용자1 생성 3-3. 사용자2 생성에 필요한 내용 준비 3-4. 사용자2 생성 3-5. 사용자1의 게시물 생성에 필요한 내용 준비 3-6. 사용자1의 게시물 생성 3-7. 사용자1의 댓글 생성에 필요한 내용 준비 3-8. 사용자1의 댓글 생성 3-9. 사용자2가 사용자1의 댓글 수정 시도 // given ❓ // when ❓ // then 검증 }제시된 수도 코드는 중복이 많아 보인다. 깔끔하게 정리해보는 미션이었다.내가 재배치한 결과는 아래와 같다.@BeforeEach void setUp() { 1-1. 사용자 생성에 필요한 내용 준비 1-2. 사용자 생성 1-3. 게시물 생성에 필요한 내용 준비 1-4. 게시물 생성 } @DisplayName("사용자가 댓글을 작성할 수 있다.") @Test void writeComment() { // given 1-5. 댓글 생성에 필요한 내용 준비 // when 1-6. 댓글 생성 // then 검증 } @DisplayName("사용자가 댓글을 수정할 수 있다.") @Test void updateComment() { // given 2-5. 댓글 생성에 필요한 내용 준비 2-6. 댓글 생성 // when 2-7. 댓글 수정 // then 검증 } @DisplayName("자신이 작성한 댓글이 아니면 수정할 수 없다.") @Test void cannotUpdateCommentWhenUserIsNotWriter() { // given 3-3. 사용자2 생성에 필요한 내용 준비 3-4. 사용자2 생성 3-7. 사용자1의 댓글 생성에 필요한 내용 준비 3-8. 사용자1의 댓글 생성 // when & then --> 예외 발생 3-9. 사용자2가 사용자1의 댓글 수정 시도 } 끝! 4주간 알차게 학습했다.미션과 발자국, 두 개 강의 모두 100% 학습해서 뿌듯하다.인프런 워밍업 클럽 스터디 GOOD!
백엔드
・
테스트
・
Junit5
・
Mockito
・
SpringRestDocs
2024. 10. 19.
0
[인프런 워밍업 클럽 스터디 2기 백엔드] 3주차 발자국
개요테스트 코드 학습을 시작했다.Practical Testing : 실용적인 테스트 가이드3주차 공부한 내용수강한 강의 영상은 얼마 안 되는 거 같지만, 러닝 타임이 어마어마하다.확실히 긴 러닝타임의 영상은 힘들다.그래도 공부할만한 내용을 배우고 있다고 되뇌이며 강의를 수강했다. 배운 것들1. TDD 적용하기TDD를 처음 해본 것은 아니다.TDD 주제 책들을 읽은 적도 있고, 직접 해 보기도 했다.TDD를 처음했을 때 깨달은 것은 "단일 클래스의 메소드를 TDD로 개발하는 것은 어렵지 않으나, 여러 계층이 있는 스프링 프로젝트에서 TDD를 적용하는 건 어렵구나. 어떻게 적용하지?" 였다. 강의를 통해서 스프링 프로젝트에서 TDD를 적용하는 방법을 배울 수 있었다. 2. DisplayName을 작성하는 법테스트 메서드의 이름이나, DisplayName을 배웠다.항상 중구난방, 기준도 없이 작성해서 고민이 많았던 내용인데,고민 해결! 3. 재고 차감시 재고가 있는지 두 번 체크하는 이유서비스에서 재고 체크 한 번, 엔티티 객체 안에서 재고 체크 한 번동일한 로직이 두 번 반복해줘야 하는 이유를 배울 수 있었다. 4. 컨트롤러에서 하는 유효성 검증, 서비스에서 하는 유효성 검증유효성 검증을 컨트롤러에서만 하는 게 아니라 계층에 맞는 유효성 검증이 있다는 것을 배웠다. 미션이번 주차에는 Day 12. 미션이 있었다. Day 12. 미션 - 읽기 좋은 코드 강의 예제 코드 단위 테스트 작성하기Readable Code: 읽기 좋은 코드를 작성하는 사고법 강의의 예제 프로젝트로 지뢰찾기와 스터디카페가 있다.둘 중 하나를 선택하여 3개의 클래스, 7개의 단위 테스트를 작성하는 것이었다.나는 스터디카페를 선택하였다.강의에서 배운 내용을 그대로 적용만 하면 되는 미션이라 수월하게 마칠 수 있었다. 마무리다음 주차 부터는 Mocking 에 대해서 배우게 된다.항상 테스트 코드를 작성할 때마다, Mocking 을 사용할 때마다 찝찝함을 느끼곤 했다.이번 기회에 제대로 정리하고 가야겠다.
백엔드
・
읽기좋은코드
・
클린코드
・
워밍업클럽
・
테스트
2024. 10. 12.
0
[인프런 워밍업 클럽 스터디 2기 백엔드] 2주차 발자국
개요2주차 종료!Readable Code: 읽기 좋은 코드를 작성하는 사고법 을 완강했다.2주차 공부한 내용목요일에 Readable Code 강의를 완강하고, 금요일 부터는 Practical Testing 강의를 수강 시작했다. 배운 것들1. 일급 컬렉션일급 컬렉션이란 걸 처음 알게 되었다.일급 시민과 컬렉션(List, Set, Map)이 합쳐진 개념이다.컬렉션을 가공하는 로직을 캡슐화할 수 있는 장점이 있다.처음 접하는 개념이라 코드로 적용하는 하는 부분에서 어려움을 느꼈다.그렇지만, 잘만 사용하면 엄청 유용한 기법이라는 생각이 든다. 2. supports()이 메서드를 Spring Security 학습하면서 많이 봤었다.그 때는 이게 왜 필요하지 했었는데, 강의를 보면서 궁금증이 해소되었던 것 같다.다형성, 객체지향에 대해서 좀 더 가까워진 느낌? 3. 주석을 어떨 때 써야하는지주석은 웬만하면 사용하지 않는 편이 좋다고 생각했다.하지만, "코드에 히스토리, 개발자의 의도를 전부 녹일 수 없을 때"에는 주석을 써야 한다는 걸 배웠다. 4. 메서드 배치 순서이거 진짜 유용했다.메서드를 어떤 기준으로 배치해야 하는지 고민이 많았었는데,덕분에 기준을 세울 수 있었다. 5. sonarlint정적 코드 분석 도구로, 인텔리제이에서 플러그인 형태로 사용 가능하다.앞으로 Stack 과 Queue 를 쓸 일이 있을 때는 무조건 Deque을 사용할 거다.sonarlint가 Deque을 사용하라고 추천해줬음. 미션이번 주차에는 Day.7 미션이 있었다. Day.7 미션 - 스터디 카페 프로젝트 리팩토링 실습하기강의에서 배운 것을 토대로 실제로 리팩토링하는 실습이었다.추상화 레벨, 일급 컬렉션, DIP, SRP 를 염두에두고 리팩토링 했다.생각보다 쉽지 않았다.스스로 해보고 답지(강의)를 보니 갈 길이 멀어보인다.나의 가장 큰 문제점은 주어진 틀에서만 해결하려고 한다는 점이다.그래서 새로운 객체를 만든다든지, 기존의 if 문들을 다른 구조로 변경하는 것에 두려움을 느끼는 것 같다.문제를 마주할 때 넓게 보는 연습이 필요한 것 같다. 차분히.리팩토링을 더 잘하기 위해서 섹션 8 - 기억하면 좋은 조언들 - 능동적 읽기 강의 내용을 적용하면 좋을 듯 하다. 공백으로 단락 구분하면서 읽기메서드와 객체로 추상화하면서 읽기주석으로 이해한 내용 표기하면서 읽기Day.7 미션을 수행할 때 위의 조언들을 적용했더라면 좀 더 나은 결과물을 얻을 수 있었을 것 같다. 마무리2주 동안 Readable Code 보면서 많이 배웠다.배운 내용들을 체화시키려면 좀 더 노력해야 할 것이다.일단은 3주차부터 테스트 코드 진도를 나가야하니 테스트 코드에 신경을 쓰도록 하고테스트 코드를 빨리 끝낼 수 있다면, Readable Code의 내용을 복습하면 좋겠다.
백엔드
・
읽기좋은코드
・
클린코드
・
워밍업클럽
・
객체지향
・
추상화
2024. 10. 05.
0
[인프런 워밍업 클럽 스터디 2기 백엔드] 1주차 발자국
개요인프런 워밍업 스터디 클럽 2기 백엔드(읽기 좋은 코드, 테스트 코드) 9/27 금요일 시작되었다.스터디 주제는 박우빈님의 강의인Readable Code: 읽기 좋은 코드를 작성하는 사고법Practical Testing: 실용적인 테스트 가이드이다.1 ~ 2주차에는 읽기 좋은 코드 강의를 수강하고, 3 ~ 4주차에는 테스트 강의를 수강 하게 되는데,이번 글은 1주차, 읽기 좋은 코드 강의를 수강하고 배운 것들을 정리해 보려고 한다. 1주차 공부한 내용발자국 작성을 위해 표로 정리했다. 생각보다 번거로운 작업이었다. 강의 하나 듣고 로그 기록하고...권장 진도표에 따르면, 섹션 5까지 1주차에 수강 하도록 되어 있는데,이번 주는 섹션 4까지가 한계였다. 생각보다 내용이 많았고, 한 번에 이해되지 않는 내용들은 복습해야 했다. 해결한 것 - 인텔리제이 한글 깨짐 이슈처음부터 난관을 겪었다.인텔리제이 한글 깨짐 이슈...강의에서는 지뢰찾기 게임을 콘솔 프로그램으로 구현이 되어 있고,콘솔에 출력되는 내용이 한글, 지뢰 모양, 네모박스 모양, 깃발 모양 등이 있는데,전부 깨져서 출력되었다.구글링을 통해 해볼 수 있는 것들은 다 해봤던 것 같다.그래도 안 되서 포기하려던 찰나, 유튜브에는 관련 내용이 없는지 살펴보았다.결국, 해결! (유튜브 만세!)Project Structure 에서 SDK와 Language level 을 17 버전으로 동일하게 맞춰주니 한글 깨짐 이슈가 해결되었다.기존에는 SDK는 21 버전이 적용되어 있었다.버전이 제대로 맞지 않으면 한글 깨짐 이슈가 일어나는구나를 깨달았다. 이미 알고 있던 것들1. 이름 짓기 이름을 잘 지어야 한 다는 것은 알고 있었다. 어려워서 그렇지...2. 메서드 추출 이거는 코드짤 때 열심히 활용하고 있다.Ctrl + Alt + M추가적으로 메서드로 추출할 때 주의사항을 설명해주셨는데 도움이 많이 되었다.메서드를 추출할 때마다 항상 주의사항 4가지를 점검해야겠다. 메서드 추출시 주의사항 4가지메서드명은 적절한가?혹시 메서드가 두 가지 일을 하고 있지는 않은가?파라미터는 적절한가?반환타입은 적절한가?왜 이 4가지를 주의 해야 하는지는 강의를 통해 확인하시라. 배운 것들1. 추상화 레벨 "하나의 세계 안에서는 추상화 레벨이 동등해야 한다." - 박우빈추상화 레벨을 동등하게 맞춰야 한다는 개념은 처음 알게 되었다.이해를 돕기 위해 들어주신 서점 비유가 와 닿았다.추상화 레벨을 맞추지 않는 것은 서점 주인이 책들 사이에 표지, 제목도 없는 종이 모음을 책 이랍시고 내놓는 것과 같다.서점에 들어갔는데 종이 모음을 보게 되면 많이 당황스러울 것 같긴 하다. ㅋㅋㅋ나는 이런 서점 주인이 되어서는 안되겠다고 다짐했다. 2. Early returnEarly return 이라는 용어는 처음 접했다.이거를 무의식적으로, 이런 용어가 있다는 것도 모른채 사용해왔던 것 같다.Early return을 사용하면 뇌 메모리의 부하를 줄일 수 있겠구나를 깨달았다. 3. orElse, orElseGet, orElseThrow의 차이자바 8 문법을 배울 때 한 번씩 사용해본 메서드들인데 이번에 제대로 정리할 수 있었다. 4. getter 사용 자제setter를 사용하지 말라는 것은 들어봤지만, getter도 사용 하지 않는 것이 좋다는 것은 처음 들었다.어쩔 수 없을 때는 getter를 써야 겠지만, 클래스를 설계할 때 무지성으로 getter를 선언하는 행동은 지양해야겠다. 미션인프런 워밍업 클럽 스터디는 강의 수강 뿐만 아니라 미션 수행도 해야 한다.이번 1주차에는 Day 2, Day 4 미션이 있었다. Day 2 미션 - 추상과 구체 예시일상 생활에서 추상과 구체에 대한 예시를 찾는 미션이었다.요즘 관심 있는 주제에서 예시를 찾으려고 했다.요즘 관심 있는 주제는 주식, 운동, 스타크래프트인데,운동 분야가 가장 설명하기 쉬워 보였고, 모든 사람이 알만한 스쿼트에 대해서 구체적으로 설명했다. Day 2 미션 답변 - 스쿼트를 구체 레벨에서 표현한다면?발을 어깨너비로 벌리고 무게중심을 발뒤꿈치에 두면서 무릎을 굽힌다.숨을 참고 복압을 유지한 상태로 엉덩이를 뒤로 밀며 허벅지가 지면과 평행해질 때까지 내려간다.하체 근육을 사용해 다시 상체를 들어 올린다.동작이 끝난 후 숨을 내쉰다. Day 4 미션 - 메서드 리팩토링 실습, SOLID 개념을 자신 만의 언어로1. 메서드 리팩터링 실습 public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; }위의 메서드를 읽기 좋은 코드로 리팩토링 해보는 미션이었다.Early return, 추상화 레벨을 맞춰주기, 공백 라인, 부정어, 이름 짓기에 주의하며 리팩터링을 수행했다.아래 코드가 리팩터링을 거친 코드public boolean validateOrder(Order order) { if (order.getItems().isEmpty()) { log.info("주문 항목이 없습니다."); return false; } if (order.isTotalPriceInvalid()) { log.info("올바르지 않은 총 가격입니다."); return false; } if (order.hasNoCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } return true; }2. SOLID 개념을 자신만의 언어로견고한 객체지향 프로그램을 위해 제시된 개념인 SOLID를 자신만의 언어로 설명하는 미션이었다.글이 너무 길어지니까 이거는 생략하겠다. 아쉬웠던 점읽기 좋은 코드로 리팩터링하기 위해서는 테스트 코드가 꼭 필요하다.원래라면 테스트 코드를 짰을 테지만, 시간이 없었다는 핑계로 테스트 코드는 건너 뛰었다.하지만, 테스트 코드 없는 리팩터링이 오히려 시간을 더 잡아먹을 수 있고, 훨씬 개발자를 불안하게 만드는 것 같다.3주차부터는 테스트 코드를 본격적으로 배우게 될텐데 기대된다. 마무리100점 짜리는 아니었지만, 내 상황에서 최선을 다한 한 주였다.미션을 제 때 낼 수 있어서 기쁘다.2주차도 잘해보자.
백엔드
・
읽기좋은코드
・
클린코드
・
워밍업클럽
・
객체지향
・
추상화