Skip to content

Commit 146d986

Browse files
authored
Merge pull request #170 from SWU-Elixir/test/157-recipe
test: RecipeService 테스트 코드 작성
2 parents 334c90c + 4669693 commit 146d986

File tree

3 files changed

+809
-1
lines changed

3 files changed

+809
-1
lines changed

src/main/java/BE_Elixir/Elixir/domain/recipe/controller/RecipeController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public ResponseEntity<CommonResponse<?>> createRecipe(
5151
// 레시피 상세 조회
5252
@GetMapping("/{recipeId}")
5353
public ResponseEntity<CommonResponse<RecipeDetailResponseDTO>> getRecipe(
54-
@PathVariable Long recipeId,
54+
@PathVariable("recipeId") Long recipeId,
5555
@AuthenticationPrincipal MemberDetails memberDetails
5656
) {
5757
Member member = memberDetails.getMember();
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
package BE_Elixir.Elixir.domain.recipe.controller;
2+
3+
import BE_Elixir.Elixir.domain.ingredient.entity.Ingredient;
4+
import BE_Elixir.Elixir.domain.member.entity.MemberDetails;
5+
import BE_Elixir.Elixir.domain.recipe.dto.response.RecipeHomeResponseDTO;
6+
import BE_Elixir.Elixir.domain.recipe.entity.Material;
7+
import BE_Elixir.Elixir.domain.recipe.entity.RecipeIngredient;
8+
import org.springframework.data.domain.Page;
9+
import org.springframework.data.domain.PageImpl;
10+
import org.springframework.data.domain.PageRequest;
11+
import org.springframework.data.domain.Pageable;
12+
import org.springframework.data.domain.Sort;
13+
import org.junit.jupiter.api.Test;
14+
import BE_Elixir.Elixir.domain.member.entity.Member;
15+
import BE_Elixir.Elixir.domain.recipe.dto.response.RecipeDetailResponseDTO;
16+
import BE_Elixir.Elixir.domain.recipe.entity.Recipe;
17+
import BE_Elixir.Elixir.domain.recipe.repository.RecipeRepository;
18+
import BE_Elixir.Elixir.domain.recipe.service.RecipeService;
19+
import BE_Elixir.Elixir.global.enums.CategorySlowAging;
20+
import BE_Elixir.Elixir.global.enums.CategoryType;
21+
import BE_Elixir.Elixir.global.enums.Difficulty;
22+
import org.junit.jupiter.api.DisplayName;
23+
import org.springframework.beans.factory.annotation.Autowired;
24+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
25+
import org.springframework.http.MediaType;
26+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
27+
import org.springframework.security.core.context.SecurityContextHolder;
28+
import org.springframework.test.context.bean.override.mockito.MockitoBean;
29+
import org.springframework.test.web.servlet.MockMvc;
30+
import org.springframework.test.web.servlet.ResultActions;
31+
32+
import java.time.LocalDateTime;
33+
import java.util.List;
34+
35+
import static org.mockito.ArgumentMatchers.*;
36+
import static org.mockito.BDDMockito.given;
37+
import static org.mockito.Mockito.mock;
38+
import static org.mockito.Mockito.when;
39+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
40+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
41+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
42+
43+
@WebMvcTest(RecipeController.class)
44+
@MockitoBean(types = {RecipeService.class, RecipeRepository.class})
45+
public class RecipeControllerTest {
46+
47+
@Autowired
48+
private MockMvc mockMvc;
49+
@Autowired
50+
private RecipeService recipeService;
51+
52+
private Member createMockMember() {
53+
Member member = mock(Member.class);
54+
when(member.getId()).thenReturn(1L);
55+
return member;
56+
}
57+
58+
// 인증 객체
59+
private void setAuthentication() {
60+
Member mockMember = createMockMember();
61+
MemberDetails memberDetails = new MemberDetails(mockMember);
62+
63+
UsernamePasswordAuthenticationToken authentication =
64+
new UsernamePasswordAuthenticationToken(memberDetails, null, List.of());
65+
SecurityContextHolder.getContext().setAuthentication(authentication);
66+
}
67+
68+
private Recipe createMockRecipe() {
69+
Recipe recipe = mock(Recipe.class);
70+
Member mockMember = createMockMember();
71+
72+
when(recipe.getMember()).thenReturn(mockMember);
73+
when(recipe.getId()).thenReturn(1L);
74+
when(recipe.getTitle()).thenReturn("테스트 레시피");
75+
when(recipe.getImageUrl()).thenReturn("https://example.com/image.jpg");
76+
when(recipe.getDescription()).thenReturn("테스트 설명");
77+
when(recipe.getCategorySlowAging()).thenReturn(CategorySlowAging.항산화강화);
78+
when(recipe.getCategoryType()).thenReturn(CategoryType.한식);
79+
when(recipe.getDifficulty()).thenReturn(Difficulty.보통);
80+
when(recipe.getTimeHours()).thenReturn(1);
81+
when(recipe.getTimeMinutes()).thenReturn(30);
82+
83+
RecipeIngredient mockTag = mock(RecipeIngredient.class);
84+
Ingredient mockIngredient = mock(Ingredient.class);
85+
when(mockIngredient.getId()).thenReturn(1L);
86+
when(mockTag.getIngredient()).thenReturn(mockIngredient);
87+
when(recipe.getIngredientTags()).thenReturn(List.of(mockTag));
88+
89+
Material mockMaterial = mock(Material.class);
90+
when(mockMaterial.getName()).thenReturn("재료/양념 1");
91+
when(mockMaterial.getValue()).thenReturn("100");
92+
when(mockMaterial.getUnit()).thenReturn("g");
93+
when(recipe.getIngredients()).thenReturn(List.of(mockMaterial));
94+
when(recipe.getSeasonings()).thenReturn(List.of(mockMaterial));
95+
96+
when(recipe.getStepDescriptions()).thenReturn(List.of("1단계 설명"));
97+
when(recipe.getStepImageUrls()).thenReturn(List.of("https://example.com/step1.jpg"));
98+
when(recipe.getTips()).thenReturn("팁");
99+
when(recipe.getLikes()).thenReturn(10);
100+
when(recipe.getCreatedAt()).thenReturn(LocalDateTime.now().minusDays(1));
101+
when(recipe.getUpdatedAt()).thenReturn(LocalDateTime.now());
102+
when(recipe.getAllergy_우유()).thenReturn(true);
103+
when(recipe.getAllergy_밀()).thenReturn(true);
104+
return recipe;
105+
}
106+
107+
@Test
108+
@DisplayName("레시피_등록")
109+
void createRecipe() throws Exception {
110+
}
111+
112+
@Test
113+
@DisplayName("레시피_상세_조회")
114+
void getRecipe() throws Exception {
115+
// given
116+
String url = "/api/recipe/1";
117+
setAuthentication();
118+
Recipe recipe = createMockRecipe();
119+
120+
RecipeDetailResponseDTO dto = new RecipeDetailResponseDTO(
121+
recipe,
122+
true,
123+
false,
124+
false
125+
);
126+
127+
given(recipeService.getRecipeDetail(eq(1L), any())).willReturn(dto);
128+
129+
// when - API 호출
130+
final ResultActions result = mockMvc.perform(get(url)
131+
.accept(MediaType.APPLICATION_JSON));
132+
133+
// then
134+
result.andExpect(status().isOk())
135+
.andExpect(jsonPath("$.data.id").value(1L))
136+
.andExpect(jsonPath("$.data.title").value("테스트 레시피"))
137+
.andExpect(jsonPath("$.data.likes").value(10 ))
138+
.andExpect(jsonPath("$.data.ingredients[0].name").value("재료/양념 1"))
139+
.andExpect(jsonPath("$.data.allergies").value(org.hamcrest.Matchers.containsInAnyOrder("우유", "밀")));
140+
}
141+
142+
@Test
143+
@DisplayName("전체_레시피_목록_조회")
144+
void getRecipes() throws Exception {
145+
// given
146+
String url = "/api/recipe";
147+
setAuthentication();
148+
149+
RecipeHomeResponseDTO dto1 = mock(RecipeHomeResponseDTO.class);
150+
RecipeHomeResponseDTO dto2 = mock(RecipeHomeResponseDTO.class);
151+
List<RecipeHomeResponseDTO> content = List.of(dto1, dto2);
152+
Pageable pageable = PageRequest.of(0, 10, Sort.by("createdAt").descending());
153+
Page<RecipeHomeResponseDTO> page = new PageImpl<>(content, pageable, content.size());
154+
given(recipeService.getRecipeList(any(Pageable.class), any())).willReturn(page);
155+
156+
// when
157+
ResultActions result = mockMvc.perform(get(url)
158+
.param("page", "0")
159+
.param("size", "10")
160+
.accept(MediaType.APPLICATION_JSON));
161+
162+
// then
163+
result.andExpect(status().isOk())
164+
.andExpect(jsonPath("$.data.content").isArray());
165+
}
166+
167+
@Test
168+
void getSearchRecipe() {
169+
}
170+
171+
@Test
172+
void getSearchKeyword() {
173+
}
174+
175+
@Test
176+
void updateRecipe() {
177+
}
178+
179+
@Test
180+
void deleteRecipe() {
181+
}
182+
183+
@Test
184+
void getMyRecipes() {
185+
}
186+
}

0 commit comments

Comments
 (0)