Spring MockMvc在我的测试中不考虑验证
问题内容:
我正在尝试使用mockMvc设置集成测试,但是我遇到了问题。实际上,spring没有集成任何验证注释。
为了更加精确,我将Controller类的代码进行了测试:
@Controller
public class UserRegisterController {
private final Log log = LogFactory.getLog(UserRegisterController.class);
private UserManager userManager;
@Autowired
public UserRegisterController(UserManager userManager){
this.userManager = userManager;
}
/**
* Register a new user.
*
*/
@RequestMapping(value = "/User/Register",
method = RequestMethod.GET
)
public @ResponseBody SimpleMessage submitForm(
@Valid UserInfoNew userInfo,
BindingResult result
){
if(log.isInfoEnabled())
log.info("Execute UserRegister action");
SimpleMessage message;
try {
if(result.hasErrors()){
if(log.isFatalEnabled())
log.fatal("Parameters sent by user for registering aren't conform. Errors are : "
+ result.getFieldErrors().toString());
throw new Exception(result.getFieldErrors().toString());
}
User user = new User();
user.setLogin(userInfo.getLogin());
user.setFamilyName(userInfo.getFamilyName());
user.setFirstName(userInfo.getFirstName());
user.setPassword(userInfo.getPassword());
user.setDateBirthday(userInfo.getDateBirthday());
user.setEmail(userInfo.getEmail());
user.setMobile(userInfo.getMobile());
user.setAddress(userInfo.getAddress());
userManager.createUser(user);
User newUser = userManager.findLastUserCreated();
//Change to null some sensitive or useless return parameters
newUser.setPassword(null);
//
message = new SimpleMessage(null, newUser);
} catch (Exception e) {
if(log.isErrorEnabled())
log.error("A problem of type : " + e.getClass()
+ " has occured, with message : " + e.getMessage());
message = new SimpleMessage(
new SimpleException(e.getClass(), e.getMessage()), null);
}
return message;
}
}
然后,具有的对象同时包含hibernate和javax批注以进行验证:
public abstract class UserParameters {
@Min(1)
protected Long id;
@Length(min=4, max=20)
protected String login;
@Length(min=4, max=20)
protected String familyName;
@Length(min=4, max=20)
protected String firstName;
@Pattern(regexp="^.*(?=.{8,20})(?=.*[a-z]+)(?=.*[a-z]+)(?=.*[A-Z]+)(?=.*[A-Z]+)"
+ "(?=.*[0-9]+)(?=.*[0-9]+)(?=.*[@$%*#]+).*$")
protected String password;
@Past
protected Calendar dateBirthday;
@Email
@Length(max=255)
protected String email;
@Pattern(regexp="^[0]{1}[67]{1}[ .-]{1}[0-9]{2}[ .-]{1}"
+ "[0-9]{2}[ .-]{1}[0-9]{2}[ .-]{1}[0-9]{2}$")
protected String mobile;
@Length(max=255)
protected String address;
protected Calendar dateCreation;
protected Calendar dateLastAccess;
}
public class UserInfoNew extends UserParameters implements Serializable{
private static final long serialVersionUID = 4427131414801253777L;
@NotBlank
public String getLogin() {
return login;
}
public void setLogin(String Login) {
this.login = Login;
}
public String getFamilyName() {
return familyName;
}
public void setFamilyName(String Name) {
this.familyName = Name;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String FirstName) {
this.firstName = FirstName;
}
@NotBlank
public String getPassword() {
return password;
}
public void setPassword(String Password){
this.password = Password;
}
public Calendar getDateBirthday() {
return dateBirthday;
}
public void setDateBirthday(Calendar strBirthDay) {
this.dateBirthday = strBirthDay;
}
public String getEmail() {
return email;
}
public void setEmail(String Mail) {
this.email = Mail;
}
@NotBlank
public String getMobile() {
return mobile;
}
public void setMobile(String Mobile) {
this.mobile = Mobile;
}
public String getAddress() {
return address;
}
public void setAddress(String Address) {
this.address = Address;
}
}
和实现测试的类:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {
WebInit_Test.class,
AppConfig_Test.class,
WebConfig_1.class,
WebConfig_2.class,
WebSocketConfig.class
})
public class UserControllersTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
.alwaysExpect(status().isOk())
.alwaysExpect(content().contentType("application/json;charset=UTF-8"))
.build();
}
@Test
public void userRegister() throws Exception {
//doesn't consider @Valid during test
mockMvc.perform(get("/User/Register?Login=A&Password=aaAA&Mobile=0134320285")
.contentType(MediaType.ALL)
)
.andExpect(jsonPath("error").exists());
}
}
当我启动测试时,错误项不存在,而登录名,密码和移动设备无法通过javax和hibernate批注进行验证。此外,当我尝试将URL发送到localhost时,验证工作正常,新用户未保存在数据库中。
如您所见,我在Web层中使用了Java代码配置,我想问题出在这里。此外,我从github上的spring团队下载了一个项目(链接:github.com/spring-
projects/spring-mvc-showcase),其中详细介绍了我们可以使用嘲笑mvcvc进行的所有测试。验证项(在“
org.springframework.samples.mvc.validation”包中)不适用于我的项目配置,但在其原始配置中效果很好。
最后,我将所有配置类发送给您
@Configuration
public class WebInit_Test extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { AppConfig_Test.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig_1.class, WebConfig_2.class, WebSocketConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected void customizeRegistration(Dynamic registration) {
registration.setInitParameter("dispatchOptionsRequest", "true");
registration.setLoadOnStartup(1);
}
}
@Configuration
@ImportResource({
"classpath:/applicationContext-dao.xml",
"classpath:/applicationContext-datasource-test.xml",
"classpath:/applicationContext-service.xml"
})
public class AppConfig_Test {
}
@Configuration
@EnableWebMvc
@ComponentScan(
basePackages = "project.web",
excludeFilters = @ComponentScan.Filter(type= FilterType.ANNOTATION, value = Configuration.class)
)
public class WebConfig_1 extends WebMvcConfigurationSupport {
@Autowired
private FormattingConversionServiceFactoryBean conversionService;
@Bean
@Override
public FormattingConversionService mvcConversionService() {
FormattingConversionService conversionService = this.conversionService.getObject();
addFormatters(conversionService);
return conversionService;
}
}
@Configuration
public class WebConfig_2 extends WebMvcConfigurerAdapter{
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/**
* Configure output mapping, see
* {@link http://stackoverflow.com/questions/4823358/spring-configure-responsebody-json-format}
* for more information
*
* @param converters
* a list of {@link HttpMessageConverter<?>}
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
converter.setObjectMapper(objectMapper);
converters.add(converter);
super.configureMessageConverters(converters);
}
}
@Configuration
//@EnableScheduling
@ComponentScan(
basePackages="project.web",
excludeFilters = @ComponentScan.Filter(type= FilterType.ANNOTATION, value = Configuration.class)
)
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/friendship", "/message", "/journey", "/information");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/client").withSockJS();
}
}
谢谢你的帮助。
问题答案:
好的,我刚刚找到了造成模拟mockmvc不考虑验证的原因。这对我的pom来说是一个很差的依赖:
我曾经
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.Final</version>
</dependency>
当我替换为
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
</dependency>
测试工作正常!
问题已经解决,但是我想知道为什么问题出在这部分。hibernate-validator 5.1.0.Final
在传递依赖项中包含javax验证,因此通常不会出现此问题。