Предыстория: Форма поиска в веб-приложении с автозаполнением/предложением. При использовании автозаполнения jQuery предложения отображаются после ввода нескольких символов. Эти предложения извлекаются в виде данных JSON с одного из контроллеров веб-приложения.
Проблема: я тестирую приложение через интеграция HtmlUnit Spring Test, которая отлично работает для текстовых/Html-страниц, но для ответов JSON здесь установка, похоже, не удалась (см. ошибку ниже).
Тестирование вручную (фактическое веб-приложение) через браузер работает, а выборка JSON с «реальных» страниц также работает (см. Тест «json()») -> Должно ли тестирование ответов JSON работать через настройку HtmlUnit/Spring Test, и если да, то что я делаешь неправильно?
Обновление (2017-06-21): использование
@ResponseBody String
и создание JSON «вручную» (не позволяя Spring делать это автоматически) работает; не совсем то, что я хотел, но, по крайней мере, я могу правильно проверить это таким образом ...
Тестовое задание:
package my.project;
import com.gargoylesoftware.htmlunit.*;
import org.junit.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.*;
import org.springframework.test.*;
import org.springframework.web.context.support.GenericWebApplicationContext;
import javax.servlet.ServletException;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestWebAppConfig.class,
// avoid context caching
MyControllerIT.class})
@WebAppConfiguration
public class MyControllerIT {
protected static final String SERVER_URL = "http://localhost";
protected WebClient webClient;
protected MockHttpServletRequest request;
protected MockHttpServletResponse response;
@Autowired
protected GenericWebApplicationContext webApplicationContext;
@Before
public void setUp() throws Exception {
this.request = new MockHttpServletRequest();
this.request.setServerName("Gondor.Osgiliath");
this.response = new MockHttpServletResponse();
this.webClient = this.initClient();
}
protected final WebClient initClient() throws ServletException {
DefaultMockMvcBuilder mockMvcBuilder = MockMvcBuilders.webAppContextSetup(this.webApplicationContext);
MockMvc mockMvc = mockMvcBuilder.build();
WebClient webClient = new WebClient();
webClient.setWebConnection(new MockMvcWebConnection(mockMvc));
return webClient;
}
// https://stackoverflow.com/questions/2932857/html-handling-a-json-response
@Test
public void json() throws Exception {
webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER, "some.proxy", 7890);
Page page = webClient.getPage("https://stackoverflow.com/users/flair/97901.json");
WebResponse webResponse = page.getWebResponse();
String contentType = webResponse.getContentType();
String contentAsString = webResponse.getContentAsString();
}
@Test
public void suggestShouldReturnJSON() throws Exception {
Page page = webClient.getPage(SERVER_URL + MyController.SUGGEST_URL + "?term=asdf");
WebResponse webResponse = page.getWebResponse();
String contentType = webResponse.getContentType();
String contentAsString = webResponse.getContentAsString();
}
@Test
public void suggestShouldReturnJSONViaMockMvc() throws Exception {
MockMvc springMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
ResultActions resultActions = springMvc.perform(MockMvcRequestBuilders
.get(MyController.SUGGEST_URL + "?term=asdf")
.accept(MediaType.APPLICATION_JSON_VALUE));
resultActions.andDo(MockMvcResultHandlers.print());
}
}
Контроллер:
package my.project;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Arrays;
import java.util.List;
@Controller
public class MyController {
public static final String SUGGEST_URL = "/suggest";
//http://api.jqueryui.com/autocomplete/#option-source
@RequestMapping(value = {SUGGEST_URL,}, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
List<Suggestion> suggest(@RequestParam(name = "term") String term) {
return Arrays.asList(new Suggestion("label1", "value1"), new Suggestion("label2", "value2"));
}
}
Конфигурация (Thymeleaf на данный момент опущен):
package my.project;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@EnableWebMvc
@ComponentScan(basePackages = {"my.project.*",})
@Configuration
@Import(ThymeleafConfig.class)
abstract class TestWebAppConfig extends WebMvcConfigurerAdapter {
}
Ошибка:
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException: 406 Not Acceptable for http://localhost/suggest?term=asdf
at com.gargoylesoftware.htmlunit.WebClient.throwFailingHttpStatusCodeExceptionIfNecessary(WebClient.java:571)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:396)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:304)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:451)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:436)
at my.project.MyControllerIt.suggestShouldReturnJSON(MyControllerIt.java:
...