프로젝트를 얼추 완성하고나서부터 빌드, 배포에 대해서 공부를 하기 시작했다. 한번에 홈서버, 네트워크, 리눅스, 환경변수, 도커, 빌드, 배포, 젠킨스, 도커 안의 도커 등의 개념을 공부하다 보니 많은 점들이 한꺼번에 주입되어 너무 헷갈렸기에 그 헷갈렸던 점들을 정리해놓고자 한다. 관심사의 분리가 이렇게 중요하구나라는 것을 깨닫게 된 좋은 계기였다. 빌드 빌드의 주체는 Gradle, Maven, Ant와 같은 빌드툴이다. 개념적으로는 알고 있었지만 젠킨스 도커 등을 공부하면서 마치 이런 툴들이 빌드까지 대신 해주는 것처럼 느껴졌다. 젠킨스가 빌드를 해주는 것이 아닌 젠킨스의 파이프라인에 빌드 단계가 들어가 빌드툴 plugin이 빌드를 한다는 개념을 정확히 잡아야 한다. 배포 배포는 AWS나 홈서버가 하는..
본인의 상황은 다음과 같았다. Docker Desktop for Windows로 Docker 이용.(Hyper-V 등과 같은 VM이 아닌) Docker에 Jenkins를 설치했고 이 Jenkins를 통해 Git과 연결하고 훅이 날라오면 Docker에 이미지를 빌드하고 Docker hub로 이미지를 푸시하는 과정이었다. Docker 내의 Jenkins를 이용하고 Jenkins 내에서 Docker를 이용하는 과정이 핵심이니 정확하게 이해하는 것이 중요하다. 도커 설정 먼저 도커허브에서 jenkins/jenkins 이미지를 받는다. (official jenkins는 deprecated 되었다.) 그다음 GUI를 통해 이미지에서 컨테이너를 몇가지 설정과 함께 바로 실행할 수 있지만 "절대로" 바로 실행해서는 안..
도커에서 포트를 열고자 할 때는 인바운드 규칙 프로그램 규칙 두 가지를 다 열어야한다. 인바운드로 포트와 아이피를 열어주는 것뿐만이 아닌 Docker Desktop Backend.exe (프로그램)의 포트 또한 오픈해야한다. 방법은 다음과 같다. 1. 도커에서 어떤 서버든 어떤 포트튼 상관없이 본인이 원하는 포트명으로 ${호스트 포트}:${컨테이너 포트}로 매핑한다. 이는 도커 내에서의 포트 포워딩 개념이므로 맨 처음에 한 번만 잘 설정해두면 건들 일이 없고 ${호스트 포트}만 기억하면 된다. 2. 공유기에서 포트 포워딩을 설정한다. 포트 포워딩은 공유기 벤더마다 약간씩 다르지만 기본적으로 크게 다르지않다. 그리고 개념적으로 헷갈리기 쉬우므로 확실하게 분리해서 생각해야 한다. 서비스 이름 : 본인이 구별..
코드를 리팩토링하면서 대부분이 코드 스멜을 스멀스멀 풍겼지만 그 중에 최악의 코드 스멜은 for loop를 돌며 findById를 매번 해오는 코드였다. 코드를 리팩토링해버려서 대충 다시 작성해보자면 다음과 같은 코드였다. for (Long myId : myIds) { myRepository.findByMyId(myId); } for문을 돌면서 값을 하나씩 받아 매번 DB I/O를 발생시키는 코드였다..😞 해당 코드는 여러 검색과 질문을 통해 다음과 같은 코드로 변경시킬 수 있었다. List findByForeignIdIn(List foreignIds); JPA의 IN clause를 사용하는 아주 간단한 해결 방법이다. IN은 범위 조건문으로 BETWEEN, LIKE처럼 사용되지만 모든 값을 일일히 입력..
forEach로 이중 for문을 돌면서 if문에 부합하면 값을 set하는 함수를 작성했다. for (ItemResponse itemResponse : itemResponses) { for (Zzim zzim : zzims) { if (itemResponse.getItemId().equals(zzim.getItem().getId())) { itemResponse.setIsZzimed(zzim.getIsZzimed()); break; } } } 모양새가 영 마음에 들지 않아 최대한 스트림으로 변환해서 사용하고자 했다. 익명의 유저에게 도움을 받아 작성한 스트림 코드는 다음과 같다. itemResponses.forEach(itemResponse -> { zzims.stream().filter(zzim -> i..
진행 중인 개인 프로젝트에서 기능을 더 이상 추가하지 않고 작성하지 않고 있었던 테스트 코드를 몰아서 작성하고 있는 중이다. 테스트 코드를 작성해야겠다라고 느낀건 기능을 작성한 이후 UI단에서 기능이 동작하는지 확인하는데까지 오랜 시간이 소요됐기 때문이다. 처음은 그냥 데이터를 꺼내어 단순히 열거만 하는 형식이었기에 테스트 자체가 필요없다고 생각했다. 하지만 문제가 생긴건 프로젝트가 조금씩 복잡해지면서 한 화면에서 필요한 기능이 여러개가 되고 또 여러 테이블을 불러와야 하고 또 WAS단에서 여러 복잡한 로직이 조금씩 추가되기 시작하면서였다. '단순히 DB에서 화면까지 잘 연결되었네'만 확인하는 수준과 여기서 이런 저런 로직이 필요해지는 수준은 또 다른 레벨이었고 이전처럼 로직이 잘 작성되었는지 UI로 확..
테스트 중인 클래스에서 이미 한 메서드의 로직을 검증했음에도 이곳 저곳에서 많이 불려서 쓰이는 경우에 해당 메서드를 모킹하여 복잡도를 줄일 수 있다. 해당 방법은 Partial Mocking이라 불리며 Spy Bean을 이용하는 방법이다. 테스트 대상을 해당 어노테이션의 순서에 맞게 설정한다.(반드시 Spy가 먼저 와야 한다.) @Spy @InjectMocks SellerService sellerService; @Spy와 @InjectMocks를 같이 쓰는건 위험하지 않을까? Each annotation has different purposes and they don't step on each other clearly as long as you need to use partial mocks. (a.k.a..
LocalDateTime이나 UUID, Random 등을 이용하는 경우 robust한 테스트를 위해서 값을 고정시킬 필요가 있다. 하지만 기본적으로 제공하는 mockito-core에서는 static 오버라이딩을 지원하지 않기에 다음과 같은 방법이 필요하다. Dependency static 메서드를 사용하기 위해 다음 dependency를 추가한다. (2022/06/19일 기준 4.6.1이 최신 버전이다.) 만약 아래의 디펜던시를 추가하지 않고 static 메서드를 모킹하려는 경우 다음과 같은 에러 메시지를 만날 것이다. The used MockMaker SubclassByteBuddyMockMaker does not support the creation of static mocks Mockito's in..
유닛 테스트 네이밍 컨벤션 테스트 네이밍 컨벤션을 따르는 것은 다른 코드 작성시의 컨벤션을 따르는 것만큼이나 장기적인 프로젝트를 진행하는데 중요하다. 널리 알려진 네이밍 컨벤션을 테스트에 적용함으로써 테스트의 이름만으로 어떤 테스트인지 이해할 수 있게 한다. 적절한 이름을 짓는 것은 어떠한 시도 적절히 번역할 수 없다는 점에서 시와 같다. ~W.H. Auden 네이밍 컨벤션을 선정하기 이전에 그 테스트가 왜 필요한지 테스트의 목적은 무엇인지 먼저 생각해보아야 한다. 테스트 네이밍을 하는데 다음과 같은 몇 가지 추천 방법이 있다. 테스트명은 특정한 필요조건을 명시해야 한다. 테스트명에는 기대되는 인풋이나 상태와 그에 상응하는 결과값을 포함시킬 수 있다. 테스트명은 워크플로우와 아웃풋을 명시하는 선언이나 사..
여태까지 공부하면서 테스트 코드가 가장 어려웠다. 테스트 자체가 어렵다기 보다는 명확하게 잘리지 않은 경계선을 명확하게 잘라내고 구분지어서 '딱 여기서부터 여기까지만. 나머지는 전부 그렇다고 쳐'의 논리 과정을 갖는 것이 쉽지 않았다. 테스트를 이해하는 데에만 시간을 꽤 많이 쏟은 것같은데 오늘 드디어 어느 정도 이해한 느낌을 받아 내용을 정리하고자 한다. 본인이 말하고자 하는 테스트란 유닛 테스트에 한하여 말한다. 유닛 테스트만 할줄 알면 통합 테스트는 식은 죽 먹기라는 말을 본 적이 있는데 그 말에 매우 동의한다. 기본 개념 스프링 내에서 혼자 살아가는 객체는 어느 무엇도 없다. 모든 객체가 크고 작은 요구를 다른 객체에게 해가며 특정 인풋에 대해 특정 액션을 하여 특정 아웃풋을 낸다. 특히 IoC로..
- Total
- Today
- Yesterday
- 루나빔
- lunarvim
- RequestPart
- IDE
- vim
- 아키텍처
- 도커
- JavaScript
- 배포
- RequestParam
- 레디스
- RequestBody
- ModelAttribute
- neovim
- Dap
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |