Модульное тестирование REST-контроллера с помощью spring-test-mvc

Я обновил свою зависимость Spring до Spring 3.1.1.RELEASE и пытаюсь использовать spring- test-mvc для модульного тестирования простого контроллера. Я следовал методике, используемой в Spring Тест контроллера REST с помощью spring -test-mvc framework, так как он, кажется, сработал для этого человека, но пока безуспешно. Я думаю, что в моем тестовом файле контекста мне не хватает какой-то ключевой конфигурации.

Я не получаю ошибок. Причина, по которой я знаю, что это не работает, заключается в том, что Hello World никогда не печатается (см. Контроллер). Что мне здесь не хватает?

Контроллер:

@Controller
@RequestMapping("/debug")
public class DebugOutputController {

    @RequestMapping(method = RequestMethod.POST)
    public void saveDebugOutput(@RequestBody DebugOutput debugOutput, HttpServletResponse response) {
        System.out.println("Hello World");
    }
}

Тестовый класс:

@RunWith(SpringJUnit4ClassRunner.class) //this lets tests access Spring beans defined in the context config file
@ContextConfiguration(locations={"file:src/test/resources/itest/restAPITestContext.xml"}) //tells the test where to get configuration and beans to be used by the test.
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,  TransactionalTestExecutionListener.class}) //overrides the default stack of listeners
public class ITRestAPI{

@Autowired
private DebugOutputController debugOutputController;

private MockMvc mockMvc;

@Before
public void setUp() throws Exception {
    mockMvc = MockMvcBuilders.standaloneSetup(debugOutputController).build();
}

@After
public void tearDown() throws Exception {
}

@Test
public void shouldPerformPost() throws Exception {
    this.mockMvc.perform(post("/debug"));
}
}

restAPITestContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <mvc:annotation-driven />
    <mvc:default-servlet-handler />
    <context:component-scan resource-pattern="*DebugOutputController*" base-package="com.company.project.servlet" />    

</beans>

person CFL_Jeff    schedule 17.05.2012    source источник
comment
spring-test-mvc действительно многообещающий, но не имеет документации. Знаете ли вы что-нибудь, кроме README на данный момент?   -  person Mike Partridge    schedule 26.07.2012
comment
@MikePartridge Вся информация, которую я нашел об этом, взята с их сайта Github.   -  person CFL_Jeff    schedule 26.07.2012


Ответы (1)


Оказывается, возникало исключение HttpMessageNotReadable, и я просто не мог его увидеть, потому что нигде не регистрировал и не печатал его. Я нашел это, создав HTTP-запрос в своем тестовом классе, используя класс DefaultRequestBuilder и добавив andDo(print()) :

DefaultRequestBuilder requestBuilder = MockMvcRequestBuilders.post("/debug").contentType(MediaType.APPLICATION_JSON).body(new String("{\"T1\":109.1, \"T2\":99.3}").getBytes());
this.mockMvc.perform(requestBuilder).andDo(print());

Итак, после этого, используя вывод andDo(print()), я мог видеть, что возникает исключение HttpMessageNotReadable, но не знал деталей исключения или его причины. Чтобы увидеть подробности, мне пришлось добавить это в класс контроллера, чтобы записать детали исключения в тело ответа:

@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseBody
public String handleException1(HttpMessageNotReadableException ex)
{
    return ex.getMessage();
}

Это выявило следующее исключение:

Could not read JSON: Unrecognized field "T1" (Class com.company.project.model.device.DebugOutput), not marked as ignorable

который я исправил, добавив аннотацию @JsonProperty к сеттерам в моем классе модели:

@JsonProperty("T1")
public void setT1(Float t1) {
    T1 = t1;
}
person CFL_Jeff    schedule 18.05.2012
comment
Что это за метод print(), который вы упомянули? Не могу найти его в тестовом классе, и, поскольку ваш тестовый класс никуда не распространяется, можете ли вы указать, откуда вы его взяли или что он делает. Спасибо. - person Mathias Conradt; 19.09.2012
comment
@MathiasLin Я использую метод print(), импортируя его статически, например так: import static org.springframework.test.web.server.result.MockMvcResultHandlers.print; Этот метод печатает сведения об отправляемом запросе. Это ОЧЕНЬ полезно при отладке. - person CFL_Jeff; 21.09.2012
comment
следует указать, что фактический оператор импорта выглядит следующим образом: import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print - person leojh; 19.12.2013