attributeExists(String key) : key에 해당하는 데이터가 model에 있는지 검증
attribute(String key, Object value1) : key에 해당하는 value가 입력해준 "value1"과 일치한지 확인
뷰 이름 검증
Java
name(String viewName) : 응답된 뷰 이름이 viewName과 일치한지 확인
리다이렉트 검증
Java
Synapse Map Insight
@WebMvcTest(PostController.class)@AutoConfigureMockMvc(addFilters =false)// 인증 필터 제외classPostControllerTest{@AutowiredprivateMockMvc mockMvc;@AutowiredprivateObjectMapper objectMapper;// JSON 변환@MockBeanprivatePostUseCase postUseCase;// 서비스 레이어 Mock@Test@DisplayName("게시글 단건 조회 - 200 OK 반환")voidgetPost_success()throwsException{// GivenPostResponse response =newPostResponse(1L,"Spring Boot 입문","PUBLISHED");given(postUseCase.findById(1L)).willReturn(response);// When & Then mockMvc.perform(get("/api/posts/1").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(jsonPath("$.id").value(1L)).andExpect(jsonPath("$.title").value("Spring Boot 입문")).andDo(print());}@Test@DisplayName("게시글 생성 - 201 Created 반환")voidcreatePost_success()throwsException{// GivenCreatePostRequest request =newCreatePostRequest("제목","내용");PostResponse response =newPostResponse(1L,"제목","DRAFT");given(postUseCase.create(any())).willReturn(response);// When & Then mockMvc.perform(post("/api/posts").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(request))).andExpect(status().isCreated()).andExpect(jsonPath("$.id").value(1L)).andDo(print());}@Test@DisplayName("존재하지 않는 게시글 조회 - 404 반환")voidgetPost_notFound()throwsException{// Givengiven(postUseCase.findById(999L)).willThrow(newResourceNotFoundException("Post not found: 999"));// When & Then mockMvc.perform(get("/api/posts/999")).andExpect(status().isNotFound()).andExpect(jsonPath("$.message").value("Post not found: 999"));}}
@Test@WithMockUser(username ="user", roles ="USER")// 인증된 사용자 시뮬레이션@DisplayName("인증된 사용자는 게시글 조회 가능")voidauthenticated_returnsPost()throwsException{given(postUseCase.findById(1L)).willReturn(newPostResponse(1L,"제목","PUBLISHED")); mockMvc.perform(get("/api/posts/1")).andExpect(status().isOk());}
classControllerTest{@AutowiredprivateMockMvc mockMvc;// mockMvc 생성// 실제로 생성자에서 주입하는 것이 더 좋음@TestpublicvoidtestController()throwsException{String jjson ="{\"name\": \"부대찌개\"}";//mockMvc에게 컨트롤러에 대한 정보를 입력하자. mockMvc.perform(get("test?query=food")//해당 url로 요청을 한다..contentType(MediaType.APPLICATION_JSON)// Json 타입으로 지정.content(jjson)// jjson으로 내용 등록.andExpect(status().isOk())// 응답 status를 ok로 테스트.andDo(print());// 응답값 print)}}
@DisplayName("View 컨트롤러 - 게시글")@WebMvcTestclassArticleControllerTest{privatefinalMockMvc mvc;publicArticleControllerTest(@AutowiredMockMvc mvc){// 테스트 패키지에서는 의존성 주입이 필요 this.mvc = mvc;}@DisplayName("[view] [GET] 게시글 리스트 (게시판) 페이지 - 정상 호출")@TestpublicvoidgivenNothing_whenRequestArticlesView_thenReturnsArticlesView()throwsException{// Given // When & Then mvc.perform(get("/articles")) .andExpect(status().isOk()).andExpect(content().contentType(MediaType.TEXT_HTML)).andExpect(model().attributeExists("articles"));}}## MockMvc[**메서드(Method)**](/vault/메서드method)### @ContextHierychy- 테스트용 [**DI(DependencyInjection)**](/vault/didependency-injection) 컨테이너 만들 때 [**Bean**](/vault/bean-2) 파일을 지정하는 [**어노테이션(Annotation)**](/vault/어노테이션annotation)이다.
```java
@ContextHierarchy({@ContextConfiguration(classes =AppConfig.class),@ContextConfiguration(classes =WebMvcConfig.class)})