测试Spring @MVC批注


问题内容

前几天,我遇到了一个问题,其中@Valid注释被意外地从控制器类中删除。不幸的是,它没有破坏我们的任何测试。我们的单元测试中没有一个实际上行使Spring
AnnotationMethodHandlerAdapter途径。我们只是直接测试我们的控制器类。

如何编写单元或集成测试,如果我的@MVC注释错误,该测试将正确失败?有什么方法可以要求Spring使用MockHttpServlet或其他东西找到并使用相关的控制器吗?


问题答案:

在即将发布的spring 3.2(可用的SNAPSHOT)中或通过spring-test-
mvc(https://github.com/SpringSource/spring-test-mvc),您可以这样做:

首先我们模拟验证,因为我们不想测试验证器,只是想知道是否调用了验证。

public class LocalValidatorFactoryBeanMock extends LocalValidatorFactoryBean
{
    private boolean fakeErrors;

    public void fakeErrors ( )
    {
        this.fakeErrors = true;
    }

    @Override
    public boolean supports ( Class<?> clazz )
    {
        return true;
    }

    @Override
    public void validate ( Object target, Errors errors, Object... validationHints )
    {
        if (fakeErrors)
        {
            errors.reject("error");
        }
    }
}

这是我们的测试班:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class RegisterControllerTest
{
 @Autowired
 private WebApplicationContext  wac;
 private MockMvc mockMvc;

     @Autowired
     @InjectMocks
     private RegisterController registerController;

     @Autowired
     private LocalValidatorFactoryBeanMock  validator;

  @Before
  public void setup ( )
  {
     this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
     // if you want to inject mocks into your controller
             MockitoAnnotations.initMocks(this);
  }

    @Test
    public void testPostValidationError ( ) throws Exception
    {
        validator.fakeErrors();
        MockHttpServletRequestBuilder post = post("/info/register");
        post.param("name", "Bob");
        ResultActions result = getMockMvc().perform(post);
            // no redirect as we have errors
        result.andExpect(view().name("info/register"));
    }

    @Configuration
    @Import(DispatcherServletConfig.class)
    static class Config extends WebMvcConfigurerAdapter
    {
        @Override
        public Validator getValidator ( )
        {
            return new LocalValidatorFactoryBeanMock();
        }

        @Bean
        RegisterController registerController ( )
        {
            return new RegisterController();
        }
    }
}