背景:在webapp中搜索表单,带有自动完成/建议。使用jQuery的自动完成功能,在输入几个字符后会显示建议。这些建议作为来自其中一个webapp控制器的JSON数据检索。
问题:我正在通过the HtmlUnit Integration of Spring Test测试应用程序,它适用于Text / Html Pages,但对于JSON响应,设置似乎失败(请参阅下面的错误)。
通过浏览器手动测试(实际的webapp)并从“真实”页面获取JSON也是可行的(参见“json()”测试) - >是否应该通过HtmlUnit / Spring Test设置测试JSON响应,如果是,我做错了什么?
更新(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"));
}
}
Config(暂时省略了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:
...