I want to test controller of Spring boot API with class structure as below:
Controller:
@RestController
@RequestMapping("/member-management")
@Validated
public class MemberManagementController {
private final MemberManagementService memberManagementService;
public MemberManagementController(MemberManagementService memberManagementService) {
this.memberManagementService = memberManagementService;
}
@GetMapping(value = "/view-member")
public ResponseEntity<?> viewMember(
@NotBlank(message = "username must not be blank!!")
@Size(max = 20, message = "maximum size of username id is 20!!")
@RequestParam("username") String username) {
...
}
...
Controller advice:
@ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Object> handleConstaintViolatoinException(final ConstraintViolationException ex) {
List<String> details = new ArrayList<>();
Set<ConstraintViolation<?>> violations = ex.getConstraintViolations();
for (ConstraintViolation<?> violation : violations) {
details.add(violation.getMessage());
}
ApiErrorResUtil error = new ApiErrorResUtil(String.valueOf(HttpStatus.BAD_REQUEST.value()),
"Request param error", details);
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
...
}
Unit test:
@RunWith(MockitoJUnitRunner.class)
public class MemberManagementControllerTest {
@InjectMocks
private MemberManagementController memberManagementController;
@Mock
private MemberManagementService memberManagementService;
private MockMvc mockMvc;
@Before // Execute before each test method
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(memberManagementController)
.setControllerAdvice(new CustomRestExceptionHandler()) // add ControllerAdvice to controller test
.build();
}
@Test
public void viewMember_usernameSizeExceedsMaximumLimit() throws Exception {
// Value from client
String username = "a12345678901234567890"; // 21 characters
MemberResDtoDataDummy memberResDtoDataDummy = new MemberResDtoDataDummy();
when(memberManagementService.viewMember(username)).thenReturn(memberResDtoDataDummy.getMember1());
mockMvc.perform(get("/member-management/view-member").param("username", username))
.andExpect(status().isBadRequest()).andReturn();
}
Problem:
java.lang.AssertionError: Status expected:<400> but was:<200>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:59)
...
Could anybody help me to resolve this proplem, why expected status is 200 instead of 400, other tests of POST, PUT, PATCH, DELETE request method with invalid inputted param are still working fine :(
standaloneSetup; it fails to set up the actual context in which a controller will be operating (JSON formatting for items such as dates is the notorious failure case). Use@SpringBootTestand autowire your MockMvc. (As a side note, you're not using standard REST conventions, and I strongly recommend you do so. Name the resource, which ismember, and "view" is already communicated by GET, soGET /members/{id}(if you know the ID) orGET /members?username=, which conventionally returns an array always because it's a search result.)