반응형

Spring 30

[Spring] JUnit5 에서 OutputCapture를 이용한 로그 테스트 해보기

최근에 우연히 로그를 테스트하는 방법에 대해 알게돼서 기록용으로 남겨보려 한다.바로 Spring Boot 에서 제공해주는 OutputCaptureExtension 이다.  Spring Boot 2.2.0 이상의 환경이라면 gradle에 별도의 추가설정 없이 사용이 가능하다.안내돼있는 것처럼, System.out, System.err 로 출력되는 코드들을 캡처해서 AssertJ, JUnit 테스트에서 로그 출력 여부를 확인할 수 있다. 참고로 @Slf4j 의 log.info, log.error 로그 출력 캡처도 가능하다.따라서 Java, Kotlin의 웬만한 환경에서는 다 사용이 가능하리라 생각한다.테스트회원가입 (signUp 메서드)을 진행하면 아래 코드와 같이 log.info 로 회원가입 로그를 찍는다..

[JUnit5] Archunit 라이브러리를 이용한 아키텍처 테스트

간혹 통합테스트를 작성하다보면 아래와 같은 생각이 들곤 한다. "비즈니스 로직이 의도한대로 작동되는지 테스트는 할 수 있겠어. 하지만 로직 외에 아키텍처 의존성을 테스트할 수는 없을까?" Archunit 라이브러리를 이용하면 아키텍처 의존성, 클래스명 등을 테스트할 수 있다! 참고로 Archunit Guide는 아래 링크에서 확인할 수 있다. https://www.archunit.org/userguide/html/000_Index.html#_introduction ArchUnit User Guide ArchUnit is a free, simple and extensible library for checking the architecture of your Java code. That is, ArchUnit..

[JPA] unique 동시성 이슈 해결 및 CountDownLatch 테스트 작성 (Feat. Unique Index)

사이드 프로젝트를 하면서 동시성 이슈를 만났다. 모바일 프론트 측에서 api 테스트를 하다가, 즐겨찾기 엔티티가 연달아 두 번 등록되는 이슈가 있었던 것이다. 그리고 즐겨찾기 엔티티는 repository에서 Optional과 같은 꼴로 반환되게 했기 때문에, 두 개 이상의 결과가 반환되면 NonUniqueResultException 가 발생한다. 이러한 동시성 이슈가 발생하는 데에는, 두 스레드가 거의 동시에 진행됐기 때문이다. 사실 트래픽이 조금이라도 많으면 이러한 동시성 이슈는 흔히 만날 수 있다. nGrinder로 save 관련 메서드에 수십개의 스레드로 테스트를 돌려보자. 아래 사진은 nGrinder로 회원가입 메서드를 수십개의 스레드로 5초동안 실행시킨 결과이다. 원래대로라면 같은 이메일, 같은..

[Spring] Elasticache Redis 캐싱과 테스트 코드를 이용한 성능 개선

해당 글에서는 aws Elasticache for Redis로 캐시 데이터를 이용한 성능 개선, Spring Boot + Lettuce Redis + JUnit5 프로덕션 + 테스트 코드에 대해 다룹니다. 사이드 프로젝트 `모카콩`의 Wiki에 작성한 글에 해당된다. 해당 프로젝트 github: https://github.com/mocacong/Mocacong-Backend GitHub - mocacong/Mocacong-Backend: 모카콩 백엔드 모카콩 백엔드. Contribute to mocacong/Mocacong-Backend development by creating an account on GitHub. github.com 들어가며 모카콩에는 수많은 카페 데이터들이 존재합니다. 전국의 카페..

[Spring] 여러 포트에서 동일 애플리케이션 실행하기(Gradle, Maven)

애플리케이션 실행 방법에는 인텔리제이 IDE, 터미널, jar파일 직접 실행과 같이 다양한 방법이 존재한다. 프로세스 여러 개를 띄울 경우, 포트 충돌 이슈를 겪을 수 있기 때문에 random port로 설정해주거나 별도로 포트 세팅을 해줄 수 있다. Spring, IntelliJ 환경에서 어떻게 여러 애플리케이션을 띄울 수 있는지 여러 방법들을 기록해보려 한다. 환경 Spring Boot 2.x IntelliJ(인텔리제이) Gradle 또는 Maven 1. 인텔리제이 edit configurations 에서 application 추가 후 VM options에서 port 변경 위 사진처럼 우측 상단에 보이는 스프링 애플리케이션 실행 부분을 클릭하면 Edit Configurations... 가 보인다. 빨..

[Spring] @Configuration vs @Component

스프링은 IoC 컨테이너를 통해 적재적소에 빈 객체를 반환해준다. @Configuration, @Component 어노테이션을 붙여주면 해당 클래스는 스프링 관리 대상이 된다는 점을 보면 크게 차이는 없어보일 수 있다. 어떠한 상황에 @Configuration을 쓰고 어떠한 상황에 @Component를 쓰는 것이 좋을까? 1. @Configuration은 @Component를 포함하고 있다 둘의 차이점을 비교하기 전에, @Configuration이 @Component를 포함하고 있다는 것을 확인하자. 그렇기 때문에 @Configuration 어노테이션이 붙여진 클래스도 @Component 어노테이션이 붙여진 클래스처럼 스프링 컨테이너 관리 대상이다. 참고로 @Component는 아래와 같이 소개돼있다. ..

[Spring] @Transactional의 전파 레벨에 대해 알아보자

스프링에선 진행중인 트랜잭션에서 다른 트랜잭션이 참여할 때의 합류조건을 설정할 수 있는 Propagation 옵션이 존재한다. DB에서 자체적으로 제공해주는 트랜잭션 격리레벨과 다르게 전파레벨은 스프링에서 개발자들의 편의를 위해 제공해주는 기능이다. 특히, 트랜잭션 격리 레벨과 마찬가지로 전파레벨은 cs 면접에서 자주 물어보는 주제이기도 하므로 잘 학습해두는 것이 좋을 듯하다. 이번 포스팅에선 트랜잭션 전파 레벨에 대해 작성해보도록 하겠다. 트랜잭션 전파 레벨은 총 7가지 트랜잭션 전파레벨에는 총 7가지 종류가 있다. 스프링 문서에 적혀있는 내용을 바탕으로 한 번 살펴보자. REQUIRED: Support a current transaction, create a new one if none exists...

[220928] 우아한테크코스 레벨4 - MVC 구현하기 미션 후기

이전에 진행됐던 `톰캣 구현하기` 미션에 이어 `MVC 구현하기` 미션이 시작됐다. 여기에서 1번은 HandlerMapping, 2번은 HandlerAdapter이다. 이번 미션에서는 위를 구현해보고 리팩터링하여 컨트롤러가 어떻게 찾아와지는지, 해당 메서드를 어떻게 실행시키고 ModelAndView로 반환시키는지 확인해보는 미션이다. 환경은 JSP 파일을 렌더링한 응답을 보내줘야 하는 SSR 환경이라고 가정한다. 1단계 - @MVC 프레임워크 구현하기 요구사항 AnnotationHandlerMappingTest가 정상 동작한다. DispatcherServlet에서 HandlerMapping 인터페이스를 활용하여 AnnotationHandlerMapping과 ManualHandlerMapping 둘다 처리..

[QueryDSL] queryDSL 프로젝트 적용 후기 및 트러블슈팅

우테코 프로젝트에서는 Spring Data JPA를 사용하고 있었다. Spring Data JPA를 이용하면 인터페이스 생성 만으로도 SimpleJpaRepository에 내장된 다양한 CRUD 메서드를 활용할 수 있고, 추가로 커스텀 메서드도 편리하게 만들 수 있다는 장점이 존재한다. 그러나 Spring Data JPA는 동적 쿼리를 사용하기 어렵고 복잡한 쿼리는 @Query 어노테이션을 이용하여 JPQL을 직접 작성해주어야 한다는 문제점이 존재한다. 따라서 이번 기회에 queryDSL을 적용하여 컴파일 시점에 문법 오류를 잡아낼 수 있게 하고, 복잡한 쿼리를 리팩터링하는 데에 도전해보았다. 특히 위처럼 DTO를 반환하는 repository method의 경우 @Query로 작성하면 DTO 패키지명을 ..

[Kotest] Nested Test spec에서의 context 생명주기 및 트랜잭션

코틀린 프로젝트에서 kotest로 테스트 코드를 짜다가 통과해야 할 테스트가 통과하지 않는 현상을 마주치게 됐다. 우리는 StringSpec과 유사한, 중첩되지 않은 구조에서 Given - When - Then 구조의 BehaviorSpec 스타일로 테스트를 마이그레이션하고 있었다. 위 두 테스트 코드는 아예 동일하다. 그저 계층만 나뉘게 바뀌었을 뿐. 구조에 따라 계층을 나누기만 하고, 순서 변경이라든지 코드의 변경이 없었으니 테스트는 당연히 문제 없이 통과할 줄 알았다. 그런데 결과는? Tests Failed... 당연히 WAITING에서 PASS로 변경될 줄 알았는데 Given에서 진행해준 update가 진행되지 않고 WAITING인 상태로 테스트가 진행됐다. 심지어 코드 변경은 전혀 없고 구조에 ..

반응형