测试Spring MVC注释映射


问题内容

使用Spring MVC,您可以指定特定的URL将由特定的方法处理,并且可以指定特定的参数映射到特定的参数,如下所示:

@Controller
public class ImageController {

   @RequestMapping("/getImage")
   public String getImage( @RequestParam("imageId") int imageId, Map<String,Object> model ) {
      model.put("image",ImageService.getImage(imageId));
   }

}

这一切都很好,但是现在我要测试带有imageId参数的http请求是否可以正确调用此方法。换句话说,我想要一个测试,如果我删除或更改任何注释,该测试将失败。有没有办法做到这一点?

很容易测试getImage是否正常工作。我可以创建一个ImageController并使用适当的参数调用getImage。但是,这只是测试的一半。测试的另一半必须是当适当的HTTP请求传入时,是否会由Spring框架调用getImage()。我觉得我也需要对该部分进行测试,尤其是当我的@RequestMapping注释变得更加复杂并调用复杂的参数时条件。

您能否告诉我一个测试,如果我删除第4行,该测试会失败@RequestMapping("getImage")


问题答案:

您可以以编程方式使用AnnotationMethodHandlerAdapter及其handle方法。这将解决给定请求的方法并执行它。不幸的是,这有点间接。实际上,ServletHandlerMethodResolver在AMHA中有一个私有类,该私有类负责仅解决给定请求的方法。我刚刚提出了对此主题进行改进请求,因为我也很希望看到这种情况。

同时,您可以使用例如EasyMock创建控制器类的模拟,期望给定的方法被调用并将该模拟传递给handle

控制器:

@Controller
public class MyController {

  @RequestMapping("/users")
  public void foo(HttpServletResponse response) {

    // your controller code
  }
}

测试:

public class RequestMappingTest {

  private MockHttpServletRequest request;
  private MockHttpServletResponse response;
  private MyController controller;
  private AnnotationMethodHandlerAdapter adapter;


  @Before
  public void setUp() {

    controller = EasyMock.createNiceMock(MyController.class);

    adapter = new AnnotationMethodHandlerAdapter();
    request = new MockHttpServletRequest();
    response = new MockHttpServletResponse();
  }


  @Test
  public void testname() throws Exception {

    request.setRequestURI("/users");

    controller.foo(response);
    EasyMock.expectLastCall().once();
    EasyMock.replay(controller);

    adapter.handle(request, response, controller);

    EasyMock.verify(controller);
  }
}

问候,奥利