22import com .bobocode .mvc .controller .NoteController ;
33import com .bobocode .mvc .data .Notes ;
44import com .bobocode .mvc .model .Note ;
5+ import lombok .SneakyThrows ;
6+ import org .junit .jupiter .api .MethodOrderer ;
7+ import org .junit .jupiter .api .Order ;
58import org .junit .jupiter .api .Test ;
9+ import org .junit .jupiter .api .TestMethodOrder ;
610import org .springframework .beans .factory .annotation .Autowired ;
711import org .springframework .boot .test .autoconfigure .web .servlet .AutoConfigureMockMvc ;
8- import org .springframework .boot .test .autoconfigure .web .servlet .WebMvcTest ;
912import org .springframework .boot .test .context .SpringBootTest ;
1013import org .springframework .boot .test .mock .mockito .MockBean ;
14+ import org .springframework .stereotype .Controller ;
1115import org .springframework .test .web .servlet .MockMvc ;
1216import 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 ;
1424import 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 ;
1629import static org .mockito .Mockito .verify ;
1730import static org .mockito .Mockito .when ;
1831import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .get ;
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