MockMvc在我的测试中不考虑验证

MockMvc在我的测试中不考虑验证

本文介绍了Spring MockMvc在我的测试中不考虑验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用mockMvc设置集成测试,但是我遇到了问题.确实,spring没有集成任何验证注释.
为了获得更高的精度,我放置了可以测试的Controller类的代码:

I am trying to set up an integration testing with mockMvc, and i have a problem with it. Indeed, spring doesn't integrate any validation annotation.
For more precision, i put the code of the Controller class which could be tested :

@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;
    }
}

然后,同时包含休眠和javax注释的对象,以进行验证:

Then, the object with contain both hibernate and javax annotation for validation :

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),其中详细介绍了我们可以使用嘲笑mvc作的所有测试.验证项(在"org.springframework.samples.mvc.validation"包中)不适用于我的项目配置,但在其原始配置中效果很好.

最后,我将所有配置类发送给您

When i launch the test, the error item doesn't exist, whereas login, password and mobile can't be validate by javax and hibernate annotation. Moreover, when i try to send an URL to localhost, validation worked and new user is not saved in database.
As you can see, i use a java code configuration for my web layer, i suppose the problem come from it. Moreover i download a project from the spring team in github (link : github.com/spring-projects/spring-mvc-showcase) which details all kind of test we can do with mockmvc. The validation one (in "org.springframework.samples.mvc.validation" package) doesn't work with my project configuration but very well with in it's original config.

To finish, i send you all my configuration classes

@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中这只是一个坏的依赖:

我用过

Ok, I have just found what is responsible for the fact that validation was not consider by mockmvc. It's just a bad dependency in my pom:

I used

<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验证,因此通常不会出现此问题.

the test work just fine!

the problem is solved, but I am wondering why the problem comes from this part. hibernate-validator 5.1.0.Final include javax validation in transitive dependency, so normally, this problem would never have appeared.

这篇关于Spring MockMvc在我的测试中不考虑验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-11 04:27