You may see the operation check of single item validation such as Form
class written in the test of Controller
. The Controller
test is often written in advance, and if there are many test patterns, the test class will be large and readability will be poor.
Writing as a test of the Form
class reduces the amount of code and makes the test content clear.
Below, confirmed with Spring Boot 2.0.5.
Test the validation of the following ʻUserForm` class.
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Data
public class UserForm {
@NotNull
private Integer userId;
@Size(max = 2)
@NotBlank
private String userName;
}
** Validation ** Implement the following validation with annotations in each field.
userId
@NotNull
--Do not allow null
.userName
@Size(max = 2)
--The maximum number of characters is 2.@NotBlank
--Do not allow input of only null
, empty string, and half-width space.Created as a test class for the ʻUserForm` class.
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserFormTest {
@Autowired
Validator validator;
private UserForm userForm = new UserForm();
private BindingResult bindingResult = new BindException(userForm, "UserForm");
@Before
public void before() {
userForm.setUserId(1);
userForm.setUserName("Ryu-bi");
}
/**
*No error
*/
@Test
public void noError() {
validator.validate(userForm, bindingResult);
assertThat(bindingResult.getFieldError(), is(nullValue()));
}
/**
*userId is null
*/
@Test
public void userIdIsNull() {
userForm.setUserId(null);
validator.validate(userForm, bindingResult);
assertThat(bindingResult.getFieldError().getField(), is("userId"));
assertThat(bindingResult.getFieldError().getDefaultMessage(), is("must not be null"));
}
/**
*The size of userName exceeds the upper limit
*/
@Test
public void userNameSizeIsOverLimit() {
userForm.setUserName("Xiahou Dun");
validator.validate(userForm, bindingResult);
assertThat(bindingResult.getFieldError().getField(), is("userName"));
assertThat(bindingResult.getFieldError().getDefaultMessage(), is("size must be between 0 and 2"));
}
/**
*userName is null
*/
@Test
public void userNameIsNull() {
userForm.setUserName(null);
validator.validate(userForm, bindingResult);
assertThat(bindingResult.getFieldError().getField(), is("userName"));
assertThat(bindingResult.getFieldError().getDefaultMessage(), is("must not be blank"));
}
/**
*userName is an empty string
*/
@Test
public void userNameIsBlank() {
userForm.setUserName("");
validator.validate(userForm, bindingResult);
assertThat(bindingResult.getFieldError().getField(), is("userName"));
assertThat(bindingResult.getFieldError().getDefaultMessage(), is("must not be blank"));
}
/**
*userName is only a half-width space
*/
@Test
public void userNameIsOnlySpace() {
userForm.setUserName(" ");
validator.validate(userForm, bindingResult);
assertThat(bindingResult.getFieldError().getField(), is("userName"));
assertThat(bindingResult.getFieldError().getDefaultMessage(), is("must not be blank"));
}
}
You can perform validation by passing ʻorg.springframework.validation.Validator to
@Autowired and ʻuserForm
and bindingResult
to the validate
method. The validation result is in bindingResult
, so you can assert the contents.
As for how to write a test method, I think that it is good for the purpose of seeing to create a normal system state with before
and change only a part to an abnormal system with each test method and test it. ..
When asked if the Controller
test is not needed at all because the Form
class can perform unary validation tests, for example, the Controller
is converting error messages, or the Form
class is validated in the first place. If you want to check if it is, you need to test with Controller
.
However, since exhaustive tests can be suppressed by tests of the Form
class, there is no doubt that the test patterns in Controller
can be reduced.
Recommended Posts