Skip to content

Commit

Permalink
[#71] 테스트 컨테이너 적용하기 (#72)
Browse files Browse the repository at this point in the history
* refactor: test Container 적용 - 1

* refactor: test Container 적용 - 2

* refactor: test Container 적용 - 3

* refactor: test Container 적용 - 4
  • Loading branch information
hikarigin99 authored Jan 23, 2023
1 parent e87af19 commit 2afe7ad
Show file tree
Hide file tree
Showing 15 changed files with 200 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public class CommentController {
public ResponseEntity<Void> save(
@PathVariable(name = "post_id") Long postId,
@Valid @RequestBody CreateCommentRequest request,
@AuthenticationPrincipal JwtAuthentication jwt
@AuthenticationPrincipal JwtAuthentication user
) {
String userEmail = jwt.userEmail();
String userEmail = user.userEmail();
commentService.save(request, userEmail, postId);
return ResponseEntity.status(CREATED).build();
}
Expand All @@ -42,9 +42,9 @@ public ResponseEntity<Void> update(
@PathVariable(name = "post_id") Long postId,
@PathVariable(name = "id") Long commentId,
@Valid @RequestBody UpdateCommentRequest request,
@AuthenticationPrincipal JwtAuthentication jwt
@AuthenticationPrincipal JwtAuthentication user
) {
String userEmail = jwt.userEmail();
String userEmail = user.userEmail();
commentService.update(request, userEmail, commentId);
return ResponseEntity.ok().build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@RequestMapping("/api/v1/users")
@RequestMapping("/api/v1/user")
@RestController
public class UserController {

private final UserService userService;

@GetMapping("/me")
ResponseEntity<UserInfo> myPage(@AuthenticationPrincipal JwtAuthentication user) {
ResponseEntity<UserInfo> myPage(
@AuthenticationPrincipal JwtAuthentication user
) {
return ResponseEntity.ok(userService.findByEmail(user.userEmail()));
}

Expand Down
12 changes: 0 additions & 12 deletions src/main/java/com/prgrms/prolog/global/config/DatabaseConfig.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public record JwtAuthentication(String token, String userEmail) {
public JwtAuthentication {
validateToken(token);
validateUserEmail(userEmail);

}

private void validateToken(String token) {
Expand Down
23 changes: 9 additions & 14 deletions src/main/resources/application-db.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
spring:

datasource:
url: ${MYSQL_URL}
username: ${MYSQL_USERNAME}
password: ${MYSQL_ROOT_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver

# 커넥션 풀 설정
Expand All @@ -22,39 +25,31 @@ spring:
dialect: org.hibernate.dialect.MySQL8Dialect
format_sql: true

flyway:
enabled: false

messages:
encoding: UTF-8
basename: messages/exceptions/exception, messages/logs/log-form

--- # local
spring:
config.activate.on-profile: "db-local"

datasource:
url: ${db.datasource.url}
username: ${db.datasource.username}
password: ${db.datasource.password}
config:
activate.on-profile: "db-local"
import: optional:file:.env[.properties]

# SQL 로그 설정
logging:
level:
org.hibernate.SQL: debug
org.hibernate.type: trace # 파라미터 값

flyway:
enabled: false

--- # prod
spring:
config:
activate.on-profile: "db-prod"
import: optional:file:.env[.properties]

datasource:
url: ${MYSQL_URL}
username: ${MYSQL_USERNAME}
password: ${MYSQL_ROOT_PASSWORD}

# Flyway 설정
flyway:
enabled: true
Expand Down
25 changes: 25 additions & 0 deletions src/test/java/com/prgrms/prolog/config/TestContainerConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.prgrms.prolog.config;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@Testcontainers
public class TestContainerConfig {

@Container
public static MySQLContainer<?> MY_SQL_CONTAINER = new MySQLContainer("mysql:8")
.withDatabaseName("test");

@BeforeAll
static void beforeAll() {
MY_SQL_CONTAINER.start();
}

@AfterAll
static void afterAll() {
MY_SQL_CONTAINER.stop();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import com.prgrms.prolog.domain.post.repository.PostRepository;
import com.prgrms.prolog.domain.user.model.User;
import com.prgrms.prolog.domain.user.repository.UserRepository;
import com.prgrms.prolog.global.config.DatabaseConfig;
import com.prgrms.prolog.global.config.JpaConfig;

@DataJpaTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,47 @@
import static com.prgrms.prolog.utils.TestUtils.*;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*;
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.restdocs.RestDocumentationContextProvider;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.prgrms.prolog.config.RestDocsConfig;
import com.prgrms.prolog.config.TestContainerConfig;
import com.prgrms.prolog.domain.post.dto.PostRequest.CreateRequest;
import com.prgrms.prolog.domain.post.dto.PostRequest.UpdateRequest;
import com.prgrms.prolog.domain.post.service.PostService;
import com.prgrms.prolog.domain.user.repository.UserRepository;
import com.prgrms.prolog.global.jwt.JwtTokenProvider.Claims;

@AutoConfigureRestDocs
@ExtendWith(RestDocumentationExtension.class)
@Import({RestDocsConfig.class, TestContainerConfig.class})
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
class PostControllerTest {

@Autowired
private MockMvc mockMvc;

@Autowired
RestDocumentationResultHandler restDocs;
@Autowired
private ObjectMapper objectMapper;
@Autowired
Expand All @@ -45,23 +55,29 @@ class PostControllerTest {
Long postId;

@BeforeEach
void setUp() {
void setUp(WebApplicationContext webApplicationContext,
RestDocumentationContextProvider restDocumentation) {
userRepository.save(USER);
CreateRequest createRequest = new CreateRequest("테스트 제목", "테스트 내용", false);
postId = postService.save(createRequest, USER_EMAIL);
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(documentationConfiguration(restDocumentation))
.alwaysDo(restDocs)
.apply(springSecurity())
.build();
}

@Test
@DisplayName("게시물을 등록할 수 있다.")
void save() throws Exception {
CreateRequest request = new CreateRequest("생성된 테스트 제목", "생성된 테스트 내용", true);

mockMvc.perform(post("/api/v1/posts")
mockMvc.perform(RestDocumentationRequestBuilders.post("/api/v1/posts")
.header("token", JWT_TOKEN_PROVIDER.createAccessToken(claims))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request))
).andExpect(status().isCreated())
.andDo(document("post-save",
.andDo(restDocs.document(
requestFields(
fieldWithPath("title").type(JsonFieldType.STRING).description("title"),
fieldWithPath("content").type(JsonFieldType.STRING).description("content"),
Expand All @@ -74,14 +90,14 @@ void save() throws Exception {
@Test
@DisplayName("게시물을 전체 조회할 수 있다.")
void findAll() throws Exception {
mockMvc.perform(get("/api/v1/posts")
mockMvc.perform(RestDocumentationRequestBuilders.get("/api/v1/posts")
.param("page", "0")
.param("size", "10")
.contentType(MediaType.APPLICATION_JSON)
.header("token", JWT_TOKEN_PROVIDER.createAccessToken(claims)))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("post-findAll",
.andDo(restDocs.document(
responseFields(
fieldWithPath("[].title").type(JsonFieldType.STRING).description("title"),
fieldWithPath("[].content").type(JsonFieldType.STRING).description("content"),
Expand All @@ -99,11 +115,11 @@ void findAll() throws Exception {
@Test
@DisplayName("게시물 아이디로 게시물을 단건 조회할 수 있다.")
void findById() throws Exception {
mockMvc.perform(get("/api/v1/posts/{id}", postId)
mockMvc.perform(RestDocumentationRequestBuilders.get("/api/v1/posts/{id}", postId)
.contentType(MediaType.APPLICATION_JSON)
.header("token", JWT_TOKEN_PROVIDER.createAccessToken(claims)))
.andExpect(status().isOk())
.andDo(document("post-findById",
.andDo(restDocs.document(
responseFields(
fieldWithPath("title").type(JsonFieldType.STRING).description("title"),
fieldWithPath("content").type(JsonFieldType.STRING).description("content"),
Expand All @@ -123,12 +139,12 @@ void findById() throws Exception {
void update() throws Exception {
UpdateRequest request = new UpdateRequest("수정된 테스트 제목", "수정된 테스트 내용", true);

mockMvc.perform(patch("/api/v1/posts/{id}", postId)
mockMvc.perform(RestDocumentationRequestBuilders.patch("/api/v1/posts/{id}", postId)
.header("token", JWT_TOKEN_PROVIDER.createAccessToken(claims))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request))
).andExpect(status().isOk())
.andDo(document("post-update",
.andDo(restDocs.document(
requestFields(
fieldWithPath("title").type(JsonFieldType.STRING).description("title"),
fieldWithPath("content").type(JsonFieldType.STRING).description("content"),
Expand All @@ -152,7 +168,7 @@ void update() throws Exception {
@Test
@DisplayName("게시물 아이디로 게시물을 삭제할 수 있다.")
void remove() throws Exception {
mockMvc.perform(delete("/api/v1/posts/{id}", postId)
mockMvc.perform(RestDocumentationRequestBuilders.delete("/api/v1/posts/{id}", postId)
.header("token", JWT_TOKEN_PROVIDER.createAccessToken(claims))
.contentType(MediaType.APPLICATION_JSON)
).andExpect(status().isNoContent())
Expand All @@ -166,7 +182,7 @@ void isValidateTitleNull() throws Exception {

String requestJsonString = objectMapper.writeValueAsString(createRequest);

mockMvc.perform(post("/api/v1/posts")
mockMvc.perform(RestDocumentationRequestBuilders.post("/api/v1/posts")
.header("token", JWT_TOKEN_PROVIDER.createAccessToken(claims))
.contentType(MediaType.APPLICATION_JSON)
.content(requestJsonString))
Expand All @@ -180,7 +196,7 @@ void isValidateContentEmpty() throws Exception {

String requestJsonString = objectMapper.writeValueAsString(createRequest);

mockMvc.perform(post("/api/v1/posts")
mockMvc.perform(RestDocumentationRequestBuilders.post("/api/v1/posts")
.header("token", JWT_TOKEN_PROVIDER.createAccessToken(claims))
.contentType(MediaType.APPLICATION_JSON)
.content(requestJsonString))
Expand All @@ -197,7 +213,7 @@ void isValidateTitleSizeOver() throws Exception {

String requestJsonString = objectMapper.writeValueAsString(createRequest);

mockMvc.perform(post("/api/v1/posts")
mockMvc.perform(RestDocumentationRequestBuilders.post("/api/v1/posts")
.header("token", JWT_TOKEN_PROVIDER.createAccessToken(claims))
.contentType(MediaType.APPLICATION_JSON)
.content(requestJsonString))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import com.prgrms.prolog.domain.post.model.Post;
import com.prgrms.prolog.domain.user.model.User;
import com.prgrms.prolog.domain.user.repository.UserRepository;
import com.prgrms.prolog.global.config.DatabaseConfig;
import com.prgrms.prolog.global.config.JpaConfig;

@DataJpaTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@
import org.springframework.data.domain.PageRequest;
import org.springframework.transaction.annotation.Transactional;

import com.prgrms.prolog.config.TestContainerConfig;
import com.prgrms.prolog.domain.post.dto.PostRequest.CreateRequest;
import com.prgrms.prolog.domain.post.dto.PostRequest.UpdateRequest;
import com.prgrms.prolog.domain.post.dto.PostResponse;
import com.prgrms.prolog.domain.post.model.Post;
import com.prgrms.prolog.domain.post.repository.PostRepository;
import com.prgrms.prolog.domain.user.model.User;
import com.prgrms.prolog.domain.user.repository.UserRepository;
import com.prgrms.prolog.global.config.DatabaseConfig;

@Import(DatabaseConfig.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@SpringBootTest
@Transactional
@Import(TestContainerConfig.class)
class PostServiceTest {

@Autowired
Expand Down
Loading

0 comments on commit 2afe7ad

Please sign in to comment.