Skip to content

Commit 7ba35e0

Browse files
committed
GP-66 add new step-by-step reflection test
1 parent cef4a44 commit 7ba35e0

File tree

3 files changed

+447
-92
lines changed

3 files changed

+447
-92
lines changed

3-0-spring-mvc/3-0-1-hello-spring-mvc/src/test/java/NoteControllerTest.java

Lines changed: 187 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,30 @@
22
import com.bobocode.mvc.controller.NoteController;
33
import com.bobocode.mvc.data.Notes;
44
import com.bobocode.mvc.model.Note;
5+
import lombok.SneakyThrows;
6+
import org.junit.jupiter.api.MethodOrderer;
7+
import org.junit.jupiter.api.Order;
58
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.TestMethodOrder;
610
import org.springframework.beans.factory.annotation.Autowired;
711
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
8-
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
912
import org.springframework.boot.test.context.SpringBootTest;
1013
import org.springframework.boot.test.mock.mockito.MockBean;
14+
import org.springframework.stereotype.Controller;
1115
import org.springframework.test.web.servlet.MockMvc;
1216
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
17+
import org.springframework.ui.Model;
18+
import org.springframework.validation.support.BindingAwareModelMap;
19+
import org.springframework.web.bind.annotation.GetMapping;
20+
import org.springframework.web.bind.annotation.PostMapping;
21+
import org.springframework.web.bind.annotation.RequestMapping;
1322

23+
import java.util.Arrays;
1424
import java.util.List;
1525

26+
import static org.assertj.core.api.Assertions.assertThat;
27+
import static org.junit.jupiter.api.Assertions.assertNotNull;
28+
import static org.junit.jupiter.api.Assertions.assertTrue;
1629
import static org.mockito.Mockito.verify;
1730
import static org.mockito.Mockito.when;
1831
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -21,20 +34,101 @@
2134

2235
@AutoConfigureMockMvc
2336
@SpringBootTest(classes = HelloSpringMvcApp.class)
24-
public class NoteControllerTest {
37+
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
38+
class NoteControllerTest {
2539
@MockBean
2640
private Notes notes;
2741

42+
@Autowired
43+
private NoteController controller;
44+
2845
@Autowired
2946
private MockMvc mockMvc;
3047

48+
@Order(1)
3149
@Test
32-
void getAllNotes() throws Exception {
33-
List<Note> noteList = List.of(
34-
new Note("Test", "Hello, World!"),
35-
new Note("Greeting", "Hey")
36-
);
37-
when(notes.getAll()).thenReturn(noteList);
50+
void classIsMarkedAsController() {
51+
var controllerAnnotation = NoteController.class.getAnnotation(Controller.class);
52+
53+
assertNotNull(controllerAnnotation);
54+
}
55+
56+
@Order(2)
57+
@Test
58+
void requestMappingIsSpecified() {
59+
var requestMappingAnnotation = NoteController.class.getAnnotation(RequestMapping.class);
60+
var urlMapping = extractUrlMapping(requestMappingAnnotation);
61+
62+
assertThat(urlMapping).isEqualTo("/notes");
63+
}
64+
65+
@Order(3)
66+
@Test
67+
void getMappingIsImplemented() {
68+
var foundMethodWithGetMapping = Arrays.stream(NoteController.class.getDeclaredMethods())
69+
.anyMatch(
70+
method -> Arrays.stream(method.getDeclaredAnnotations())
71+
.anyMatch(a -> a.annotationType().equals(GetMapping.class))
72+
);
73+
74+
assertTrue(foundMethodWithGetMapping);
75+
}
76+
77+
@Order(4)
78+
@Test
79+
void getNotesMethodAcceptsModelAsParameter() {
80+
var getNotesMethod = Arrays.stream(NoteController.class.getDeclaredMethods())
81+
.filter(
82+
method -> Arrays.stream(method.getDeclaredAnnotations())
83+
.anyMatch(a -> a.annotationType().equals(GetMapping.class))
84+
)
85+
.findAny()
86+
.orElseThrow();
87+
88+
assertThat(getNotesMethod.getParameterCount()).isEqualTo(1);
89+
assertThat(getNotesMethod.getParameterTypes()[0]).isEqualTo(Model.class);
90+
}
91+
92+
@Order(5)
93+
@Test
94+
@SneakyThrows
95+
void getNotesMethodReturnNotesViewName() {
96+
var getNotesMethod = Arrays.stream(controller.getClass().getDeclaredMethods())
97+
.filter(
98+
method -> Arrays.stream(method.getDeclaredAnnotations())
99+
.anyMatch(a -> a.annotationType().equals(GetMapping.class))
100+
)
101+
.findAny()
102+
.orElseThrow();
103+
104+
var viewName = getNotesMethod.invoke(controller, new BindingAwareModelMap());
105+
106+
assertThat(viewName).isEqualTo("notes");
107+
}
108+
109+
@Order(6)
110+
@Test
111+
@SneakyThrows
112+
void getNotesMethodAddsNoteListToTheModel() {
113+
var noteList = givenNoteList();
114+
var model = new BindingAwareModelMap();
115+
var getNotesMethod = Arrays.stream(controller.getClass().getDeclaredMethods())
116+
.filter(
117+
method -> Arrays.stream(method.getDeclaredAnnotations())
118+
.anyMatch(a -> a.annotationType().equals(GetMapping.class))
119+
)
120+
.findAny()
121+
.orElseThrow();
122+
123+
getNotesMethod.invoke(controller, model);
124+
125+
assertThat(model.get("noteList")).isEqualTo(noteList);
126+
}
127+
128+
@Order(7)
129+
@Test
130+
void getNotes() throws Exception {
131+
var noteList = givenNoteList();
38132

39133
mockMvc.perform(get("/notes"))
40134
.andExpect(status().isOk())
@@ -43,8 +137,75 @@ void getAllNotes() throws Exception {
43137
.andExpect(model().attribute("noteList", noteList));
44138
}
45139

140+
@Order(8)
141+
@Test
142+
void postMappingIsImplemented() {
143+
var foundMethodWithGetMapping = Arrays.stream(NoteController.class.getDeclaredMethods())
144+
.anyMatch(
145+
method -> Arrays.stream(method.getDeclaredAnnotations())
146+
.anyMatch(a -> a.annotationType().equals(PostMapping.class))
147+
);
148+
149+
assertTrue(foundMethodWithGetMapping);
150+
}
151+
152+
@Order(9)
153+
@Test
154+
void addNoteMethodAcceptsNewNoteAsParameter() {
155+
var addNoteMethod = Arrays.stream(NoteController.class.getDeclaredMethods())
156+
.filter(
157+
method -> Arrays.stream(method.getDeclaredAnnotations())
158+
.anyMatch(a -> a.annotationType().equals(PostMapping.class))
159+
)
160+
.findAny()
161+
.orElseThrow();
162+
163+
assertThat(addNoteMethod.getParameterCount()).isEqualTo(1);
164+
assertThat(addNoteMethod.getParameterTypes()[0]).isEqualTo(Note.class);
165+
166+
}
167+
168+
@Order(10)
169+
@Test
170+
@SneakyThrows
171+
void addNoteMethodReturnsRedirectToNotes() {
172+
var addNoteMethod = Arrays.stream(NoteController.class.getDeclaredMethods())
173+
.filter(
174+
method -> Arrays.stream(method.getDeclaredAnnotations())
175+
.anyMatch(a -> a.annotationType().equals(PostMapping.class))
176+
)
177+
.findAny()
178+
.orElseThrow();
179+
180+
181+
var response = addNoteMethod.invoke(controller, new Note("Test", "Hello, World!"));
182+
183+
assertThat(response).isEqualTo("redirect:/notes");
184+
}
185+
186+
@Order(11)
46187
@Test
47-
void addNote() throws Exception {
188+
@SneakyThrows
189+
void addNotePassPostedNote() {
190+
var note = new Note("Test", "Hello, World!");
191+
var addNoteMethod = Arrays.stream(NoteController.class.getDeclaredMethods())
192+
.filter(
193+
method -> Arrays.stream(method.getDeclaredAnnotations())
194+
.anyMatch(a -> a.annotationType().equals(PostMapping.class))
195+
)
196+
.findAny()
197+
.orElseThrow();
198+
199+
200+
addNoteMethod.invoke(controller, note);
201+
202+
verify(notes).add(note);
203+
}
204+
205+
@Order(12)
206+
@Test
207+
@SneakyThrows
208+
void addNote() {
48209
Note note = new Note("Test", "Hello, World!");
49210

50211
mockMvc.perform(post("/notes")
@@ -56,4 +217,21 @@ void addNote() throws Exception {
56217

57218
verify(notes).add(note);
58219
}
220+
221+
private String extractUrlMapping(RequestMapping requestMapping) {
222+
if (requestMapping.value().length > 0) {
223+
return requestMapping.value()[0];
224+
} else {
225+
return requestMapping.path()[0];
226+
}
227+
}
228+
229+
private List<Note> givenNoteList() {
230+
List<Note> noteList = List.of(
231+
new Note("Test", "Hello, World!"),
232+
new Note("Greeting", "Hey")
233+
);
234+
when(notes.getAll()).thenReturn(noteList);
235+
return noteList;
236+
}
59237
}

0 commit comments

Comments
 (0)