我写使用Spring MVC REST服务。 下面是类的轮廓:
@Controller
public class MyController{
@RequestMapping(..)
public void myMethod(...) throws NotAuthorizedException{...}
@ExceptionHandler(NotAuthorizedException.class)
@ResponseStatus(value=HttpStatus.UNAUTHORIZED, reason="blah")
public void handler(...){...}
}
我一直在使用贴设计写我的单元测试在这里 。 该试验基本上如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(....)
public class mytest{
MockHttpServletRequest requestMock;
MockHttpServletResponse responseMock;
AnnotationMethodHandlerAdapter handlerAdapter;
@Before
public void setUp() {
requestMock = new MockHttpServletRequest();
requestMock.setContentType(MediaType.APPLICATION_JSON_VALUE);
requestMock.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
responseMock = new MockHttpServletResponse();
handlerAdapter = new AnnotationMethodHandlerAdapter();
}
@Test
public void testExceptionHandler(){
// setup ....
handlerAdapter.handle(...);
// verify
// I would like to do the following
assertThat(responseMock.getStatus(), is(HttpStatus.UNAUTHORIZED.value()));
}
}
然而,该呼叫handle
被扔NotAuthorizedException
。 我已阅读,这是由设计为能够单元测试,该方法抛出适当的异常,但是我想编写的自动测试,该框架被适当地处理该异常,并且,根据试验类已经适当地执行的处理程序。 有没有办法做到这一点?
请注意,我没有进入到实际的代码中,我可以将它张贴的地方。
此外,我有限(不幸的原因)到Spring 3.0.5或3.1.2。
请考虑使用Spring 3.2和MVC测试框架
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml")
public class WebMvcTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void getFoo() throws Exception {
this.mockMvc.perform(
get("/testx")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
)
.andExpect(status().isUnauthorized());
}
}
控制器代码
@Controller
public class MyController {
public class MyException extends RuntimeException {
};
@RequestMapping("/testx")
public void myMethod() {
throw new MyException();
}
@ExceptionHandler(MyException.class)
@ResponseStatus(value = HttpStatus.UNAUTHORIZED, reason = "blah")
public void handler() {
System.out.println("handler processed");
}
}
这种“测试”经过好。
免责声明:目前我在Spring MVC中测试一个小白,其实这是我的第一次测试。
UPD:感谢德雷克的修正 。
注释与异常处理的控制器@ControllerAdvice
而不是@Controller
。
正如鲍里斯Treukhov加入时指出@ExceptionHandler
在抛出控制器注释的方法异常会使其工作,但只能从特定的控制器。
@ControllerAdvice
将让你的异常HANDELING方法适用于您的整个应用程序而不只是一个特定的控制器。
你可以改变@Test来
@Test(expected=NotAuthorizedException.class)
如果内部扔了该异常,否则为false这将返回true。
这也将使assertThat()是不必要的。 你可以写映入NotAuthorizedException那么你可以检查该条件下的responseMock再进行第二次测试。