Skip to content

Commit

Permalink
Merge pull request #148 from qp-official-org/test/147
Browse files Browse the repository at this point in the history
[test] QuestionController.createQuestion 테스트 코드 작성
  • Loading branch information
Leewonchan14 authored Feb 13, 2024
2 parents bfdf3ae + 073f7e2 commit 8918065
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 2 deletions.
2 changes: 0 additions & 2 deletions src/main/java/qp/official/qp/QpBackendApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

import javax.annotation.PostConstruct;
import java.util.TimeZone;

@SpringBootApplication
@EnableJpaAuditing
public class QpBackendApplication {

static {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package qp.official.qp.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@Configuration
@EnableJpaAuditing
public class JpaEnversConfiguration {
}
21 changes: 21 additions & 0 deletions src/main/java/qp/official/qp/config/ObjectMapperConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package qp.official.qp.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

import static java.nio.charset.StandardCharsets.UTF_8;

@Configuration
public class ObjectMapperConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.stream()
.filter(converter -> converter instanceof MappingJackson2HttpMessageConverter)
.findFirst()
.ifPresent(converter -> ((MappingJackson2HttpMessageConverter) converter).setDefaultCharset(UTF_8));
}
}
1 change: 1 addition & 0 deletions src/main/java/qp/official/qp/domain/Question.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import qp.official.qp.web.dto.QuestionRequestDTO;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
public class QuestionController {
private final QuestionCommandService questionCommandService;
private final QuestionQueryService questionQueryService;
private final TokenService tokenService;

// 질문 작성
@PostMapping
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package qp.official.qp.web.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import qp.official.qp.apiPayload.ApiResponse;
import qp.official.qp.domain.Hashtag;
import qp.official.qp.domain.Question;
import qp.official.qp.domain.User;
import qp.official.qp.repository.HashtagRepository;
import qp.official.qp.repository.UserRepository;
import qp.official.qp.service.QuestionService.QuestionCommandService;
import qp.official.qp.service.QuestionService.QuestionQueryService;
import qp.official.qp.service.TokenService.TokenService;
import qp.official.qp.web.dto.QuestionRequestDTO;
import qp.official.qp.web.dto.QuestionResponseDTO;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

// WebMvcTest를 사용하여 QuestionController를 테스트
// WebMvcTest는 Controller가 의존하는 Bean들만 로드하여 테스트
@WebMvcTest(QuestionController.class)
class QuestionControllerTest {

@MockBean
private QuestionCommandService questionCommandService;
@MockBean
private QuestionQueryService questionQueryService;

// ExistHashTag 어노테이션에서 사용하는 HashtagRepository
@MockBean
private HashtagRepository hashtagRepository;

// ExistUser 어노테이션에서 사용하는 UserRepository
@MockBean
private UserRepository userRepository;

@MockBean
private TokenService tokenService;

// MockMvc를 사용하여 API를 테스트
private final MockMvc mockMvc;

// ObjectMapper를 사용하여 객체를 JSON으로 변환 또는 JSON을 객체로 변환
private final ObjectMapper objectMapper;

@Autowired
public QuestionControllerTest(
MockMvc mockMvc,
ObjectMapper objectMapper
) {
this.mockMvc = mockMvc;
this.objectMapper = objectMapper;
}

@Test
void createQuestion() throws Exception {
// given
String testTitle = "new title";
String testContent = "new content";

Long userId = 1L;
Long questionId = 1L;
LocalDateTime createdAt = LocalDateTime.now();

// Request 객체 생성
QuestionRequestDTO.CreateDTO questionRequest = QuestionRequestDTO.CreateDTO.builder()
.userId(userId)
.title(testTitle)
.content(testContent)
.hashtag(new ArrayList<>())
.build();


// Expect Response 객체 생성
Question questionResponse = Question.builder()
.questionId(questionId)
.title(testTitle)
.content(testContent)
.answers(new ArrayList<>())
.build();

// Setter 없이 ReflectionTestUtils를 사용하여 필드값을 설정
ReflectionTestUtils.setField(questionResponse, "createdAt", createdAt);

// questionCommandService 에서 createQuestion 메소드가 호출될 때 questionResponse를 반환하도록 설정
when(questionCommandService.createQuestion(any(QuestionRequestDTO.CreateDTO.class))).thenReturn(questionResponse);
// ExistUser 어노테이션을 통과하기 위해 userRepository 에서 findById 메소드가 호출될 때 아무 Optional.of(User.builder().build())를 반환하도록 설정
when(userRepository.findById(any(Long.class))).thenReturn(Optional.of(User.builder().build()));
// ExistHashTag 어노테이션을 통과하기 위해 hashtagRepository 에서 findById 메소드가 호출될 때 아무 Optional.of(Hashtag.builder().build())를 반환하도록 설정
when(hashtagRepository.findById(any(Long.class))).thenReturn(Optional.of(Hashtag.builder().build()));

// when
// Request 객체를 JSON으로(request body로) 변환
String body = objectMapper.writeValueAsString(questionRequest);
// API 호출
ResultActions action = mockMvc.perform(MockMvcRequestBuilders.post("/questions")
.contentType("application/json")
.content(body));

// then
// API 호출 결과가 200 OK인지 확인
action.andExpect(status().isOk());

// API 호출 결과를 ApiResponse 객체로 변환
ApiResponse<QuestionResponseDTO.CreateResultDTO> response = objectMapper.readValue(
action.andReturn().getResponse().getContentAsString(),
new TypeReference<>() {
}
);

// questionId 확인
assertEquals(questionId, response.getResult().getQuestionId());

// createAt 확인
assertEquals(createdAt, response.getResult().getCreatedAt());
}
}

0 comments on commit 8918065

Please sign in to comment.