pab*_*gdt 2 testing ajax jquery json htmlunit
我有一个Web应用程序,当我向服务器发出AJAX请求以进行CRUD操作时返回JSON.这是因为我使用jQuery来处理数据而不刷新页面(MVC),所以如果我在系统中创建一个新条目,服务器将返回一个响应,该响应具有JSON格式的创建条目.jQuery管理收到的数据并在列表中呈现条目(使用先前创建的条目).
现在我用HTML单元测试它,但是如果我尝试的话
WebResponse response = page.getWebResponse()
Run Code Online (Sandbox Code Playgroud)
我得到200状态并且消息"OK".但我期待着我创建的条目的JSON数据.
如果我试试
page.asText()
Run Code Online (Sandbox Code Playgroud)
我得到当前页面的HTML(条目已经在列表中,但不是我想要的数据).
这是一个类似的问题,没有回应:Json ajax调用返回响应200 ok
PD:jQuery表单有两个字段,一个是名称的文本输入,另一个是汽车设置的选择.我将要选择的设置列表传递给此函数.使用时间戳和静态int种子自动生成名称.这是我正在使用的代码:
public void create(List<Settings> settings) throws FailingHttpStatusCodeException, MalformedURLException, IOException
{
page = webClient.getPage("localhost:8080/cars/list");
int elementsCount = getEntitiesCount();
creationSeed = elementsCount+1;
HtmlAnchor anchor = (HtmlAnchor) page.getFirstByXPath("//a[@class='action-createCar']");
page = (HtmlPage) anchor.click();
HtmlForm form = page.getFirstByXPath("//form[@class='CarsForm']");
form = page.getForms().get(0);
HtmlTextInput nameField = form.getInputByName("CarsForm-name");
nameField.setText("Test " + creationSeed + " - " + new Date().getTime());
HtmlSelect columnSelectList = (HtmlSelect) form.getSelectByName("CarsForm-settings");
if (settings != null && settings.size() > 0)
for (Settings setting : settings)
{
HtmlOption htmlOption = columnSelectList.getOptionByValue(setting.name());
htmlOption.setSelected(true);
}
//looking for the button to submit the form
HtmlDivision buttonSet = page.getFirstByXPath("//div[@class='ui-dialog-buttonset']");
HtmlButton okButton = (HtmlButton) buttonSet.getFirstElementChild();
page = okButton.click();
assertEquals(elementsCount + 1, getEntitiesCount());
//Here is where I want to get the server response to check the data which is returned by the server
//And neither page.getWebResponse() or page.asText() contains it
}
Run Code Online (Sandbox Code Playgroud)
}
小智 8
我遇到了类似的问题,并使用HtmlUnit FAQ页面找到了解决方案:
您可以将HttpWebConnection子类化并覆盖getResponse(),如下所示:
Run Code Online (Sandbox Code Playgroud)new WebConnectionWrapper(webClient) { public WebResponse getResponse(WebRequest request) throws IOException { WebResponse response = super.getResponse(request); if (request.getUrl().toExternalForm().contains("my_url")) { String content = response.getContentAsString("UTF-8"); //change content WebResponseData data = new WebResponseData(content.getBytes("UTF-8"), response.getStatusCode(), response.getStatusMessage(), >response.getResponseHeaders()); response = new WebResponse(data, request, response.getLoadTime()); } return response; } };
这意味着我们可以包装我们的webClient对象,拦截我们需要的任何请求和响应,提取它们或进行更改.
我创建了一个扩展WebConnectionWrapper的内部类,并且有一个我需要的JSON字段:
private class JsonResponseWebWrapper extends WebConnectionWrapper{
public JsonResponseWebWrapper(WebClient webClient){
super(webClient);
}
String jsonResponse;
@Override
public WebResponse getResponse(WebRequest request) throws IOException {;
WebResponse response = super.getResponse(request);
//extract JSON from response
jsonResponse = response.getContentAsString();
return response;
}
public String getJsonResponse() {
return jsonResponse;
}
};
Run Code Online (Sandbox Code Playgroud)
这样我们就会拦截每一个响应.但首先我们需要包装webClient.我在请求JSON响应之前就这样做了,所以我没有必要为我的包装器添加条件:
JsonResponseWebWrapper jrww = new JsonResponseWebWrapper(webClient);
page = button.click();
String rawJSON = jrww.getJsonResponse();
Run Code Online (Sandbox Code Playgroud)
之后,您可以使用自己喜欢的JSON解析器解析它.希望这可以帮助!