Подтвердить что ты не робот

Тестирование Spring MVC аннотации mapppings

С помощью 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));
   }

}

Это хорошо и хорошо, но теперь я хочу проверить, что HTTP-запрос с параметром imageId вызовет этот метод правильно. Другими словами, я хочу тест, который сломается, если я удалю или изменю любые аннотации. Есть ли способ сделать это?

Легко проверить, что getImage работает правильно. Я мог бы просто создать ImageController и вызвать getImage с соответствующими аргументами. Однако это всего лишь половина теста. Другая половина теста должна состоять в том, будет ли getImage() вызываться структурой Spring, когда приходит соответствующий HTTP-запрос. Я чувствую, что мне также нужен тест для этой части, тем более что мои аннотации @RequestMapping становятся больше сложный и вызывать сложные параметры параметров.

Не могли бы вы показать мне тест, который сломается, если я удалю строку 4, @RequestMapping("getImage")?

4b9b3361

Ответ 1

Вы можете использовать AnnotationMethodHandlerAdapter и его метод handle программно. Это решит метод для данного запроса и выполнит его. К сожалению, это немного косвенно. На самом деле в AMHA есть частный класс под названием ServletHandlerMethodResolver, который отвечает за простое решение метода для данного запроса. Я просто подал запрос на улучшение по этой теме, так как я действительно хотел бы, чтобы это было возможно.

Тем временем вы можете использовать, например, 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);
  }
}

С уважением, Олли

Ответ 2

Решение Ollie охватывает тестирование конкретного примера аннотации, но как насчет более широкого вопроса о том, как тестировать все другие различные аннотации MV7. Мой подход (который можно легко распространить на другие аннотации) будет

import static org.springframework.test.web.ModelAndViewAssert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({/* include live config here
    e.g. "file:web/WEB-INF/application-context.xml",
    "file:web/WEB-INF/dispatcher-servlet.xml" */})
public class MyControllerIntegrationTest {

    @Inject
    private ApplicationContext applicationContext;

    private MockHttpServletRequest request;
    private MockHttpServletResponse response;
    private HandlerAdapter handlerAdapter;
    private MyController controller;

    @Before
    public void setUp() {
       request = new MockHttpServletRequest();
       response = new MockHttpServletResponse();
       handlerAdapter = applicationContext.getBean(HandlerAdapter.class);
       // I could get the controller from the context here
       controller = new MyController();
    }

    @Test
    public void testFoo() throws Exception {
       request.setRequestURI("/users");
       final ModelAndView mav = handlerAdapter.handle(request, response, 
           controller);
       assertViewName(mav, null);
       assertAndReturnModelAttributeOfType(mav, "image", Image.class);
    }
}

Я также написал запись в блоге об интеграции тестирования Spring аннотации MVC.