๋ณธ ํ๋ก์ ํธ๋ โ์คํ๋ง๋ถํธ 3 ๋ฐฑ์๋ ๊ฐ๋ฐ์ ๋๊ธฐโ ์์ ์ ์ฐธ๊ณ ํ์ฌ ์งํํ์์
OAuth ์ธ์ฆ ์ ์ฉ ์ํ ํ
์คํธ ์ฝ๋ ์์ฑ
โขํ
์คํธ์ฝ๋ ์์ - ๊ตต์ ๊ธ์จ๋ก ํ์ํ ๋ถ๋ถ ์ฐธ๊ณ
package com.example.msblog.controller;
import com.example.msblog.domain.Article;
import com.example.msblog.domain.User;
import com.example.msblog.dto.AddArticleRequest;
import com.example.msblog.dto.UpdateArticleRequest;
import com.example.msblog.repository.BlogRepository;
import com.example.msblog.repository.UserRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import java.security.Principal;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest // ํ
์คํธ์ฉ ์ ํ๋ฆฌ์ผ์ด์
์ปจํ์คํธ
@AutoConfigureMockMvc // MockMvc ์์ฑ ๋ฐ ์๋ ๊ตฌ์ฑ
class BlogApiControllerTest {
@Autowired
protected MockMvc mockMvc;
@Autowired
protected ObjectMapper objectMapper; // ์ง๋ ฌํ, ์ญ์ง๋ ฌํ๋ฅผ ์ํ ํด๋์ค
@Autowired
private WebApplicationContext context;
@Autowired
BlogRepository blogRepository;
// ์ถ๊ฐ
@Autowired
UserRepository userRepository;
// ์ถ๊ฐ
User user;
// ์ถ๊ฐ
@BeforeEach
@Test
void setSecurityContext() {
userRepository.deleteAll();
user = userRepository.save(User.builder()
.email("user@gmail.com")
.password("test")
.build());
// ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๋ ์ํ๋ฆฌํฐ ์ฝํ
์คํธ์ setAuthentication() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด ํ
์คํธ ์ ์ ๋ฅผ ์ง์ ํ๋ค.
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(new UsernamePasswordAuthenticationToken(user,
user.getPassword(), user.getAuthorities()));
}
@BeforeEach // ํ
์คํธ ์คํ ์ ์คํํ๋ ๋ฉ์๋
public void mockMvcSetUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
blogRepository.deleteAll();
}
@DisplayName("addArticle: ๋ธ๋ก๊ทธ ๊ธ ์ถ๊ฐ์ ์ฑ๊ณตํ๋ค.")
@Test
public void addArticle() throws Exception {
// given
final String url = "/api/articles";
final String title = "title";
final String content = "content";
final AddArticleRequest userRequest = new AddArticleRequest(title, content);
// ๊ฐ์ฒด JSON์ผ๋ก ์ง๋ ฌํํ๊ธฐ
final String requestBody = objectMapper.writeValueAsString(userRequest);
// ์ถ๊ฐ - ๊ธ์ ์์ฑํ๋ API์์๋ ํ๋ผ๋ฏธํฐ๋ก Principal ๊ฐ์ฒด๋ฅผ ๋ฐ๊ณ ์๋๋ฐ ์ด ๊ฐ์ฒด์ ํ
์คํธ ์ ์ ๊ฐ ๋ค์ด๊ฐ๋๋ก ๋ชจํนํ๋ค.
// ํด๋น ํ
์คํธ ์ฝ๋์์๋ Principal ๊ฐ์ฒด๋ฅผ ๋ชจํนํด์ ์คํ๋ง ๋ถํธ ์ ํ๋ฆฌ์ผ์ด์
์์ getName() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด "userName" ์ด๋ผ๋ ๊ฐ์ ๋ฐํํ๋ค.
Principal principal = Mockito.mock(Principal.class);
Mockito.when(principal.getName()).thenReturn("username");
// when
// mockMvc ํ์ฉํ์ฌ HTTP ๋ฉ์๋, URL, ์์ฒญ ๋ณธ๋ฌธ, ์์ฒญ ํ์
๋ฑ์ ์ค์ ํ ๋ค ์ค์ ํ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ํ
์คํธ ์์ฒญ์ ๋ณด๋
// ์ค์ ํ ๋ด์ฉ ๋ฐํ์ผ๋ก ์์ฒญ ์ ์ก
ResultActions result = mockMvc.perform(post(url)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.principal(principal) // ์ถ๊ฐ
.content(requestBody));
// then
result.andExpect(status().isCreated());
List<Article> articles = blogRepository.findAll();
assertThat(articles.size()).isEqualTo(1); // ํฌ๊ธฐ๊ฐ 1์ธ์ง ๊ฒ์ฆ
assertThat(articles.get(0).getTitle()).isEqualTo(title);
assertThat(articles.get(0).getContent()).isEqualTo(content);
}
@DisplayName("findAllAritcles: ๋ธ๋ก๊ทธ ๊ธ ๋ชฉ๋ก ์กฐํ์ ์ฑ๊ณตํ๋ค.")
@Test
public void findAllArticles() throws Exception {
// given
final String url = "/api/articles";
Article savedArticle = createDefaultArticle(); // ์ถ๊ฐ
// when
final ResultActions resultActions = mockMvc.perform(get(url)
.accept(MediaType.APPLICATION_JSON));
// then
resultActions
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].content").value(savedArticle.getContent())) // ์์
.andExpect(jsonPath("$[0].title").value(savedArticle.getTitle())); // ์์
}
@DisplayName("findArticle: ๋ธ๋ก๊ทธ ๊ธ ์กฐํ์ ์ฑ๊ณตํ๋ค.")
@Test
public void findArticle() throws Exception {
// given
final String url = "/api/articles/{id}";
Article savedArticle = createDefaultArticle(); // ์ถ๊ฐ
// when
final ResultActions resultActions = mockMvc.perform(get(url, savedArticle.getId()));
// then
resultActions
.andExpect(status().isOk())
.andExpect(jsonPath("$.content").value(savedArticle.getContent())) // ์์
.andExpect(jsonPath("$.title").value(savedArticle.getTitle())); // ์์
}
@DisplayName("deleteArticle: ๋ธ๋ก๊ทธ ๊ธ ์ญ์ ์ ์ฑ๊ณตํ๋ค.")
@Test
public void deleteArticle() throws Exception {
// given
final String url = "/api/articles/{id}";
Article savedArticle = createDefaultArticle(); // ์ถ๊ฐ
// when
mockMvc.perform(delete(url, savedArticle.getId()))
.andExpect(status().isOk());
// then
List<Article> articles = blogRepository.findAll();
assertThat(articles).isEmpty();
}
@DisplayName("updateArticle: ๋ธ๋ก๊ทธ ๊ธ ์์ ์ ์ฑ๊ณตํ๋ค.")
@Test
public void updateArticle() throws Exception {
// given
final String url = "/api/articles/{id}";
Article savedArticle = createDefaultArticle(); // ์ถ๊ฐ
final String newTitle = "new title";
final String newContent = "new content";
UpdateArticleRequest request = new UpdateArticleRequest(newTitle, newContent);
// when
ResultActions result = mockMvc.perform(put(url, savedArticle.getId())
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsString(request)));
// then
result.andExpect(status().isOk());
Article article = blogRepository.findById(savedArticle.getId()).get();
assertThat(article.getTitle()).isEqualTo(newTitle);
assertThat(article.getContent()).isEqualTo(newContent);
}
// ์ค๋ณต ์ฝ๋ ์ ๊ฑฐํ๊ธฐ ์ํด ๊ธ์ ๋ง๋๋ ๋ก์ง์ ํด๋น ๋ฉ์๋๋ก ์ถ์ถํ๋ค.
private Article createDefaultArticle() {
return blogRepository.save(Article.builder()
.title("title")
.author(user.getUsername())
.content("content")
.build());
}
}
ํต์ฌ ์์ฝ