I have an issue with testing my Spring Boot Controller I'm trying to solve for the past few hours. I'm quite new to coding, but I got that assignment in my company nevertheless.
My Controller:
@GetMapping(value = "/data", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> getData(@RequestParam("core") List<String> core, @RequestParam("date") List<String> date,
@RequestParam("state") String state, @RequestParam("area") List<String> area,
@RequestParam("type") List<String> type, @RequestParam("analyt") String analyt,
@RequestParam("wp") String wp, @RequestParam("subDesc") String subDesc,
@RequestParam("anaMonitor") List<String> anaMonitor, @RequestParam("ecoMonitor") List<String> ecoMonitor,
@RequestParam("subType") List<String> subType, @RequestParam("needed") List<String> needed,
@RequestParam("notify") List<String> notify, @RequestParam("available") List<String> available,
@RequestParam("phase") List<String> phase, @RequestParam("subAvailable") List<String> subAvailable,
@RequestParam("subShipped") List<String> subShipped, @RequestParam("external") List<String> external,
@RequestParam("valid") List<String> valid, @RequestParam("contract") List<String> contract) {
FilterInputModel model = new FilterInputModel(core, date, state, type, area, analyt, wp, subDesc, anaMonitor, ecoMonitor, subType, needed, notify, available, phase, subAvailable, subShipped, external, valid, contract);
return new ResponseEntity<>(vaultService.getFilteredFields(model), HttpStatus.OK);
}
Here's a test:
@DisplayName("Controller Test")
@AutoConfigureMockMvc
@WebMvcTest(controllers = Controller.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
class ControllerTest {
@Autowired
private MockMvc mockMvc;
private FilterInputModel model;
@MockBean
private TestService testService;
@Autowired
ControllerTest() {
}
@BeforeEach
void setup() {
MockitoAnnotations.openMocks(this);
@Test
void getDataTest() throws Exception {
List<Object> response = new ArrayList<>();
when(vaultService.getFilteredFields(model))
.thenReturn(response)
.thenReturn(HttpStatus.OK);
this.mockMvc.perform(
MockMvcRequestBuilders.get("/api/data")
.contentType(MediaType.APPLICATION_JSON_VALUE)
.accept("application/json"))
.andExpect(MockMvcResultMatchers.status().isOk());
.andExpect(result -> assertEquals(response, result.getAsyncResult()));
}
And here's an answer I got. It says in an error message that 'Required request parameter 'core' for method parameter type List is not present' but that answer didn't help me much. I'm still stuck looking for an answer.
MockHttpServletRequest:
HTTP Method = GET
Request URI = /api/data
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json"]
Body = null
Session Attrs = {}
Handler:
Type = hr.ogcs.ltt.api.lttapi.controller.LttController
Method = hr.ogcs.ltt.api.lttapi.controller.LttController#getData(List, List, String, List, List, String, String, String, List, List, List, List, List, List, List, List, List, List, List, List)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.bind.MissingServletRequestParameterException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 400
Error message = Required request parameter 'core' for method parameter type List is not present
Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers"]
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Status expected:<200> but was:<400>
Expected :200
Actual :400
<Click to see difference>
java.lang.AssertionError: Status expected:<200> but was:<400>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:122)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:627)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:212)
at hr.ogcs.ltt.api.apicontroller.ControllerTest.getDataTest(ControllerTest.java:126) <31 internal lines>
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)<9 internal lines>
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)<48 internal lines>
CodePudding user response:
You are not sending the required parameters (the parameters annotated with @RequestParam
) to the method. By default they are all required. If not present Spring blocks the request with missing arguments.
Example of sending parameters:
mvc.perform(
MockMvcRequestBuilders.get("/public/xpto/{code}", "21212").param("core", "ubababacaio")
.contentType(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON_VALUE).characterEncoding("UTF-8")).andExpect(status().isOk());