-
Database local dev환경 구성하기(postgreSQL with Docker)프로젝트/선착순 쿠폰 발급 시스템 2023. 4. 29. 00:01728x90
개요
별다른 설정 없이도 Spring Boot가 지원하는 in-memory H2 Database 덕분에 JPA를 활용하여 API요청 테스트를 수행할 수 있었습니다.
local 환경에는 h2 database를 dev환경에는 postgreSQL로 구성해 보고자 합니다.
application-infra.yml 설정
--- spring: profiles: active: on-profile : local h2: console: enabled: true jpa: database-platform: org.hibernate.dialect.H2Dialect hibernate: ddl-auto: none datasource: hikari: connectionTimeout: 30000 idleTimeout: 60000 maxLifetime: 1800000 url: jdbc:h2:mem:reader username: sa password: null driverClassName: org.h2.Driver --- spring: profiles: active: on-profile : dev h2: console: enabled: true jpa: database-platform: org.hibernate.dialect.H2Dialect hibernate: ddl-auto: none datasource: hikari: connectionTimeout: 30000 idleTimeout: 60000 maxLifetime: 1800000 url: jdbc:h2:mem:reader username: sa password: null driverClassName: org.h2.Driver
단일 datasource이며 우선 local과 dev의 환경을 h2로 구성해보고자 했습니다.
Local 환경 DB 테스트
infrastructure 모듈에 테스트를 만들어 보겠습니다.
SpringBootApplication
@SpringBootApplication(scanBasePackages = ["com.demo.infrastructure"]) class SpringBootApplication { }
테스트의 Spring Bean scan을 위해서 구성하였습니다.
SignUpTest
package com.demo.infrastructure.member.signup import com.demo.domain.member.entity.Member import com.demo.infrastructure.member.signup.adapter.MemberPersistenceAdapter import com.demo.infrastructure.member.signup.repository.MemberJpaRepository import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.ActiveProfiles @SpringBootTest @ActiveProfiles("local") internal class SignUpTest @Autowired constructor( val memberJpaRepository: MemberJpaRepository, val memberPersistenceAdapter: MemberPersistenceAdapter, ){ @Test fun `초기 데이터베이스 상태는 member를 가지고 있지 않아야 한다`(){ //given val empty = 0 //when val memberCount = memberJpaRepository.findAll().size //then Assertions.assertEquals(memberCount, empty) } @Test fun `회원을 가입한 경우 회원을 조회할 수 있어야 한다`(){ //given val member = Member.testFixture() //when memberPersistenceAdapter.save(member) //then val memberCount = memberJpaRepository.findAll().size Assertions.assertEquals(memberCount, 1) } }
ActiveProfiles를 통해 local환경을 테스트하고자 했습니다.
추후에는 dev로 바꾸어 postgreSQL에서도 테스트하고자 합니다.
위에서 SpringBootApplication을 테스트환경에 만들어두었기 때문에 @SpringBootTest를 수행하면 com.demo.infrastructure 하위 패키지의 bean을 scan 할 수 있게 됩니다.
Dev 환경 DB 구축
docker를 활용하여 postgreSQL을 할 예정입니다.
이전에 kafka를 위해 사용했던 docker-compose.yml에 postgreSQL을 구축했습니다.
#docker-compose.yml version: '2' services: zookeeper: container_name: local-zookeeper image: wurstmeister/zookeeper ports: - "2181:2181" kafka: container_name: local-kafka image: wurstmeister/kafka depends_on: - zookeeper ports: - "9092:9092" environment: KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1 KAFKA_ADVERTISED_PORT: 9092 KAFKA_CREATE_TOPICS: "test:1:1" #topic이름:partition개수:replica개수 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 volumes: - /var/run/docker.sock:/var/run/docker.sock db: container_name: coupon image: 'postgres:13.1-alpine' ports: - "5432:5432" environment: - POSTGRES_DB=coupon_db - POSTGRES_USER=root - POSTGRES_PASSWORD=1234
위의 zookeeper, kafka 부분은 무시하고 db 쪽 설정만 추가해 줍니다.
postgres 13 docker image를 받아 database이름은 root 비밀번호는 1234로 설정합니다.
application-infra.yml dev-profile 수정
spring: profiles: active: on-profile : dev h2: console: enabled: true jpa: database-platform: org.hibernate.dialect.PostgreSQLDialect hibernate: ddl-auto: none datasource: hikari: connectionTimeout: 30000 idleTimeout: 60000 maxLifetime: 1800000 url: jdbc:postgresql://localhost:5432/coupon_db username: root password: 1234 driverClassName: org.postgresql.Driver
테스트를 위한 application.yml 작성
테스트를 위해 테스트하는 부분에 resources를 만들고 application.yml을 작성합니다.
application-infra.yml과 동일합니다.
하지만 ddl-auto 부분을 update로 변경합니다
이유는 현재 JPA entity에 해당하는 Table을 따로 생성해주지 않았기 때문입니다.
Docker-Compose UP
docker-compose up 명령어를 수행했으나 port binding에서 이미 사용 중이라는 에러가 나왔습니다.
natstat을 이용하여 5432 port를 조회했으나 사용 중인 어떤 port도 조회되지 않았습니다.
에러 해결을 위해 docker-compose 관련하여 여러 시도를 해보았지만 재부팅 후 해결되었습니다..
Docker PostgreSQL Clean Up
docker-compose down --volumes
volumes 가 계속 저장되기 때문에 이미 생성되어 있다면 계속 데이터가 쌓이게 됩니다.
만약 clean up을 하고 싶다면 위의 명령어를 통해 해결할 수 있습니다.
gradle 특정(dev) profile만 테스트하도록 하기
./gradlew clean test -Pprofile=dev
dev profile만 test 할 수 있도록 하는 gradlew 명령어입니다.
SignUpTest
package com.demo.infrastructure.member.signup import com.demo.domain.member.entity.Member import com.demo.infrastructure.member.signup.adapter.MemberPersistenceAdapter import com.demo.infrastructure.member.signup.repository.MemberJpaRepository import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.ActiveProfiles import org.springframework.transaction.annotation.Transactional @SpringBootTest @ActiveProfiles("dev") @Transactional internal class SignUpTest @Autowired constructor( val memberJpaRepository: MemberJpaRepository, val memberPersistenceAdapter: MemberPersistenceAdapter, ){ @Test fun `초기 데이터베이스 상태는 member를 가지고 있지 않아야 한다`(){ //given val empty = 0 //when val memberCount = memberJpaRepository.findAll().size //then Assertions.assertEquals(memberCount, empty) } @Test fun `회원을 가입한 경우 회원을 조회할 수 있어야 한다`(){ //given val member = Member.testFixture() //when memberPersistenceAdapter.save(member) //then val memberCount = memberJpaRepository.findAll().size Assertions.assertEquals(memberCount, 1) } }
이전에 작성하였던 테스트에서 local -> dev로 바꾸어 테스트를 실행해 보면 정상적으로 동작하는 것을 확인할 수 있습니다.
또한 @Transactional 애노테이션을 추가해 테스트가 수행 후 rollback 되도록 만들어 재사용이 가능해졌습니다.
'프로젝트 > 선착순 쿠폰 발급 시스템' 카테고리의 다른 글
Event Driven Architecture란? (0) 2023.05.01 Spring Boot Flyway 적용하기(flyway, h2 DB test 에러 해결) (0) 2023.04.30 회원 도메인 모듈 만들기 (0) 2023.04.27 gradle build 속도 개선하기 (0) 2023.04.25 gradlew build 에러 해결 과정 기록 (0) 2023.04.24