I would like to write some unit test to test the @Valid of SpringBoot request, hopefully, without having to spin the server.
For instance, in the "old way", one could write a piece of code like this:
record SomeRequest(String clientId) { }
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
class FieldValidationController {
@PostMapping("/validate")
String question(@RequestBody SomeRequest someRequest) {
validateRequestOldFashionWay(someRequest);
return "please validate the field";
}
//Not using @Valid here
public void validateRequestOldFashionWay(SomeRequest someRequest) {
if (someRequest.clientId() == null || someRequest.clientId().isEmpty()) {
throw new IllegalArgumentException("clientId cannot be null or empty");
}
}
}
@Test
public void clientIdEmptyTestWithoutHavingToStartSpring() throws Exception {
FieldValidationController controller = new FieldValidationController();
SomeRequest someRequest1 = new SomeRequest("");
assertThrows(IllegalArgumentException.class, () -> controller.validateRequestOldFashionWay(someRequest1));
SomeRequest someRequest3 = new SomeRequest("good");
controller.validateRequestOldFashionWay(someRequest3);
}
As you can see above, it is a straightforward test on the validation method.
There is no need to spin up the server, bring in mockmvc, etc
Now, moving the code to Spring validation:
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
record SomeRequest(@NotNull @NotEmpty String clientId) { }
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
class FieldValidationController {
@PostMapping("/validate")
String question(@Valid @RequestBody SomeRequest someRequest) {
return "please validate the field";
}
}
I understand I can write a unit test which looks like this to test the validation feature.
@WebMvcTest(FieldValidationController.class)
class FieldValidationControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void clientIdNotNullTest() throws Exception {
SomeRequest someRequest = new SomeRequest("notNullTest");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
ObjectWriter ow = mapper.writer().withDefaultPrettyPrinter();
String requestJson=ow.writeValueAsString(someRequest);
mvc.perform(post("/validate").contentType(APPLICATION_JSON_UTF8)
.content(requestJson))
.andExpect(status().isOk());
}
But this would need to spin up spring, it looks more like an integration test now.
To keep the question simple, how can I test the same functionality, without having to spin up spring?