์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- ์์ ํ์
- HashMap
- ๋ฌ๋น์บ ํผ์ค
- Algorithm
- ๋ ธ๋ง๋์ฝ๋
- dfs
- ๋ฌ๋นํด๋ฝ1๊ธฐ
- ์ฌ๊ท
- Array
- ๋ฆฌ์กํธ
- Java
- ๋ฐฑ์ค
- ์ธํ๋ ์ด์ ์์ ์ด์๋จ๊ธฐ
- ๋ ธ๋ง๋์ฝ๋ ๊ฐ์
- ReactJS๋ก ์ํ ์น ์๋น์ค ๋ง๋ค๊ธฐ
- BOJ
- Stack
- programmers
- React
- SoftwareExpertAcademy
- ์๋ฐ
- SWEA
- ๋ฌ๋นํด๋ฝ
- ์๊ณ ๋ฆฌ์ฆ
- ๊ฒฝ์ ๊ณต๋ถ
- JPA
- ํ๋ก๊ทธ๋๋จธ์ค
- ๋ฌ๋นํด๋ฝ 1๊ธฐ
- ์นด์นด์ค๋ธ๋ผ์ธ๋์ฝ๋ฉํ ์คํธ
- React.js
- Today
- Total
th42500์ TIL
[Test] MockTest ์ค ๋ฐ์ํ 401 (Unauthorized) ์๋ฌ ๋ณธ๋ฌธ
[Test] MockTest ์ค ๋ฐ์ํ 401 (Unauthorized) ์๋ฌ
th42500 2023. 1. 1. 14:02๐ ๊ฐ๋ฐํ๊ฒฝ
Editor : Intellij Ultimate
Deb Tool : SpringBoot 2.7.5
JDK : JAVA 11
Build : Gradle 6.8
Server : AWS EC2
DB : MySql 8.0
Library : SpringBoot Web, MySQL, Spring Data JPA, Lombok, Spring Security
โ ๊ธฐ๋ฅ Test ์งํ ์ค ๋ฐ์ํ 401 Error โ
์ต๊ทผ Mock์ ์ด์ฉํ BDD ๊ธฐ๋ฐ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ์ฐ์ต์ ํ๊ณ ์๋ค. ํ ์คํธ ์ฝ๋๋ฅผ ์ด์ฉํ ๊ธฐ๋ฅ ํ ์คํธ ์งํ ์ค 401Error๋ฅผ ๋ง์ฃผ์ณค๋ค.
import com.fasterxml.jackson.databind.ObjectMapper;
import com.likelion.healing.domain.dto.CommentReq;
import com.likelion.healing.domain.entity.CommentEntity;
import com.likelion.healing.domain.entity.PostEntity;
import com.likelion.healing.domain.entity.UserEntity;
import com.likelion.healing.service.CommentService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
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.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import java.time.LocalDateTime;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(CommentController.class)
class CommentControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
CommentService commentService;
@Autowired
ObjectMapper objectMapper;
@Nested
@DisplayName("๋๊ธ ๋ฑ๋ก ํ
์คํธ")
class AddCommentTest{
@Test
@DisplayName("๋๊ธ ๋ฑ๋ก ์ฑ๊ณต")
void successfulAddComment() throws Exception {
CommentReq req = CommentReq.builder()
.comment("comment")
.build();
CommentEntity comment = CommentEntity.builder()
.id(1)
.comment("comment")
.post(PostEntity.builder().id(3).build())
.user(UserEntity.builder().userName("user").build())
.build();
LocalDateTime nowTime = LocalDateTime.now();
comment.setCreatedAt(nowTime);
comment.setUpdatedAt(nowTime);
given(commentService.addCommentByPostId(any(Integer.class), any(CommentReq.class), any(String.class)))
.willReturn(comment);
mockMvc.perform(post(String.format("/api/v1/posts/%d/comments", 3))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.id").value(1))
.andExpect(jsonPath("$.result.comment").value("comment"))
.andExpect(jsonPath("$.result.postId").value(3))
.andExpect(jsonPath("$.result.userName").value("user"))
.andExpect(jsonPath("$.result.createdAt").exists())
.andExpect(jsonPath("$.result.lastModifiedAt").exists());
}
}
}
๐ 401(Unauthorized) ๊ฐ ๋ฌด์จ ์๋ฌ์ผ๊น
401์๋ฌ๋ Unauthorized๋ฅผ ์๋ฏธํ๋ฉฐ, ํด๋น ๊ธฐ๋ฅ์ ์์ฒญํ ํด๋ผ์ด์ธํธ๊ฐ ์ฆ๋ช ๋์ง ์์ ์ํ์ด๊ธฐ ๋๋ฌธ์ ์์ฒญ์ด ๊ฑฐ๋ถ๋์๋ค๋ ์๋ฏธ์ด๋ค. ์ฆ, ํด๋ผ์ด์ธํธ๊ฐ ์ธ์ฆ๋์ง ์์ ์์ฒญ์ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์์ ์๋ฏธํ๋ ์ํ์ฝ๋์ด๋ค.
ํด๋น ์๋ฌ๋ 403์๋ฌ์ธ Forbidden๊ณผ ์ ์ฌํด๋ณด์ด์ง๋ง ์ ํ ๋ค๋ฅด๋ค. 403 ์๋ฌ๋ ์ฆ๋ช ๋ ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ์ ํ์์ง๋ง ํด๋น ๋ฆฌ์์ค๋ฅผ ์ด์ฉํ ๊ถํ์ด ์์ด ๋ฐ์ํ๋ ๊ฒ์ด๋ค.
์ฝ๊ฒ ์์๋ฅผ ๋ค์๋ฉด, ๋ค์๊ณผ ๊ฐ๋ค.
401 - ๋ก๊ทธ์ธ์ด ์๋ ์ฌ์ฉ์๊ฐ ๊ฒ์๊ธ์ ๊ธ์ฐ๊ธฐ๋ฅผ ์์ฒญ
403 - ํ์์ผ๋ก ๋ก๊ทธ์ธํ ์ฌ์ฉ์๊ฐ ๊ด๋ฆฌ์ ํ์ด์ง๋ก ์ด๋ํ๊ธฐ๋ฅผ ์์ฒญ
๐ก ํด๊ฒฐ ๋ฐฉ๋ฒ
Test Class ์๋จ์ @WithMockUser๋ฅผ ์ ์ธํจ์ผ๋ก์จ ์ธ์ฆ๋ ์ํ์ User๋ฅผ ๊ฐ์ ํ ์ํ์์ Test๋ฅผ ์งํํจ์ผ๋ก์จ ํด๊ฒฐํ ์ ์์๋ค.
package com.likelion.healing.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.likelion.healing.domain.dto.CommentReq;
import com.likelion.healing.domain.entity.CommentEntity;
import com.likelion.healing.domain.entity.PostEntity;
import com.likelion.healing.domain.entity.UserEntity;
import com.likelion.healing.service.CommentService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
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.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import java.time.LocalDateTime;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(CommentController.class)
@WithMockUser(username = "user") // โจ
class CommentControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
CommentService commentService;
@Autowired
ObjectMapper objectMapper;
@Nested
@DisplayName("๋๊ธ ๋ฑ๋ก ํ
์คํธ")
class AddCommentTest{
@Test
@DisplayName("๋๊ธ ๋ฑ๋ก ์ฑ๊ณต")
void successfulAddComment() throws Exception {
CommentReq req = CommentReq.builder()
.comment("comment")
.build();
CommentEntity comment = CommentEntity.builder()
.id(1)
.comment("comment")
.post(PostEntity.builder().id(3).build())
.user(UserEntity.builder().userName("user").build())
.build();
LocalDateTime nowTime = LocalDateTime.now();
comment.setCreatedAt(nowTime);
comment.setUpdatedAt(nowTime);
given(commentService.addCommentByPostId(any(Integer.class), any(CommentReq.class), any(String.class)))
.willReturn(comment);
mockMvc.perform(post(String.format("/api/v1/posts/%d/comments", 3))
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(req)))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.resultCode").value("SUCCESS"))
.andExpect(jsonPath("$.result.id").value(1))
.andExpect(jsonPath("$.result.comment").value("comment"))
.andExpect(jsonPath("$.result.postId").value(3))
.andExpect(jsonPath("$.result.userName").value("user"))
.andExpect(jsonPath("$.result.createdAt").exists())
.andExpect(jsonPath("$.result.lastModifiedAt").exists());
}
}
}
์ ์๋ MockUser๋ "user"๋ผ๋ userName๊ณผ "password"๋ผ๋ password ๊ทธ๋ฆฌ๊ณ "ROLE_USER"๋ผ๋ ๊ถํ์ ๊ฐ๊ณ ์์์ ๊ฐ์ ํด์ฃผ์ด ๋์ด์ 401(Unathorized)๊ฐ ๋ฐ์ํ์ง ์์ ๊ฒ์ ํ์ธํ ์ ์์๋ค.
์ฐธ๊ณ ๋ฌธ์
https://developer.mozilla.org/ko/docs/Web/HTTP/Status/401
401 Unauthorized - HTTP | MDN
์ด ์ํ๋ WWW-Authenticate (en-US) ํค๋์ ํจ๊ป ์ ์ก๋๋ฉฐ, ์ด ํค๋๋ ์ฌ๋ฐ๋ฅด๊ฒ ์ธ์ฆํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ ๋ณด๋ฅผ ํฌํจํ๊ณ ์์ต๋๋ค.
developer.mozilla.org
18. Testing
There are a number of options available to associate a user to the current HttpServletRequest. For example, the following will run as a user (which does not need to exist) with the username "user", the password "password", and the role "ROLE_USER": You can
docs.spring.io
https://catsbi.oopy.io/f9b0d83c-4775-47da-9c81-2261851fe0d0
์คํ๋ง ์ํ๋ฆฌํฐ ์ฃผ์ ์ํคํ ์ฒ ์ดํด
๋ชฉ์ฐจ
catsbi.oopy.io
'Backend > JUnit & BDD' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
MockTest ์ null ๊ฐ์ด ๋จ๋ ์ด์ (0) | 2023.01.26 |
---|---|
[JUnit] @Nested๋? (0) | 2023.01.04 |
Given-When-Then ํจํด๊ณผ given()&when() (0) | 2023.01.03 |