概述
一、背景
因为原来采用过Rhino(JS解析引擎,新版JDK中也默认包含另外一个解析引擎)来在Java环境中解析JavaScript并运行其中的方法。最近看到有人在问题里提问,模拟Ajax请求的问题。所以就想看看有没有方法通过Rhino来实现Ajax请求的模拟。
二、分析
通过上网检索,发现可以采用Envjs,一个纯js方式在无浏览器环境下模拟浏览器的行为,并且与Rhino有集成。这样我就可以实现用Java来处理孤立js中的Ajax请求。
三、开发
1、项目目录结构
main中my.js为要测试的JavaScript,jquery-1.9.1.js为依赖。
test中AjaxTest.java为单元测试类,test.html为测试页面,env.rhino.1.2.js为Envjs依赖。
2、my.js(Jquery的ajax)
function myFunction(id) {
$.ajax({
url:"/ajaxservice",
type:"POST",
data:{id:id},
dataType:"json",
success:function (msg) {
$("#log").text(msg.name);
}
});
}
这个myFunction实际上就是调用了Jquery的ajax来请求ajaxservice,并把返回的json对象中的name显示在id为log的元素中。
3、test.html
/p>
"http://www.w3.org/TR/html4/loose.dtd">
需要测试的my.js并不包含任何页面为了测试my.js的功能需要先有一个页面来模拟Ajax请求,并对返回操作做出响应。
4、AjaxTest.java单元测试类
package org.noahx.ajaxtest;
import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.util.resource.Resource;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.ScriptableObject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
/**
* Created with IntelliJ IDEA.
* User: noah
* Date: 4/8/13
* Time: 9:21 PM
* To change this template use File | Settings | File Templates.
*/
public class AjaxTest {
private static int port = 18080;
private static String testUrl = "http://127.0.0.1:" + port + "/test.html";
private Context cx;
private ScriptableObject scope;
@BeforeClass
public static void prepareHttpService() throws Exception {
Server server = new Server(port);
ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setBaseResource(Resource.newClassPathResource("/org/noahx/ajaxtest/html"));
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{resourceHandler, new AjaxHandler()});
server.setHandler(handlers);
server.start();
}
public static class AjaxHandler extends AbstractHandler {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if ("/ajaxservice".equals(target)) {
System.out.println("id=" + request.getParameter("id"));
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
baseRequest.setHandled(true);
response.getWriter().println("{"name":"张三"}"); //返回json "name":"张三"
}
}
}
@Before
public void prepareRhinoContext() throws Exception {
//初始化rhino
cx = ContextFactory.getGlobal().enterContext();
cx.setOptimizationLevel(-1);
cx.setLanguageVersion(Context.VERSION_1_5);
scope = cx.initStandardObjects();
//预制js验证与调试方法
String printFunction = "function print(message) {java.lang.System.out.println(message);}";
String assertEqualsNumFunction = "function assertEqualsNum(a,b) {org.junit.Assert.assertEquals(a,b,1e-15);}";
String assertNotEqualsNumFunction = "function assertNotEqualsNum(a,b) {org.junit.Assert.assertNotEquals(a,b,1e-15);}";
String assertEqualsStrFunction = "function assertEqualsStr(a,b) {org.junit.Assert.assertEquals(a,b);}";
String assertNotEqualsStrFunction = "function assertNotEqualsStr(a,b) {org.junit.Assert.assertNotEquals(a,b);}";
cx.evaluateString(scope, printFunction, "print", 1, null);
cx.evaluateString(scope, assertEqualsNumFunction, "assertEqualsNum", 1, null);
cx.evaluateString(scope, assertNotEqualsNumFunction, "assertNotEqualsNum", 1, null);
cx.evaluateString(scope, assertEqualsStrFunction, "assertEqualsStr", 1, null);
cx.evaluateString(scope, assertNotEqualsStrFunction, "assertNotEqualsStr", 1, null);
loadJS("env.rhino.js", "/org/noahx/ajaxtest/env.rhino.1.2.js"); //加载Envjs
}
@Test
public void testJqueryAjax() throws Exception {
loadJS("jquery.js", "/org/noahx/ajaxtest/jquery-1.9.1.js"); //加载jquery
loadJS("my.js", "/org/noahx/ajaxtest/my.js"); //加载要测试的js
run("window.location = "" + testUrl + """); //加载测试js的测试html
run("assertEqualsStr($("#log").text(),"ilog");"); //从test.html中取log元素中的text,应该为ilog
run("myFunction("myid123");");
run("Envjs.wait();"); //Envjs等待,模拟异步ajax响应
run("assertEqualsStr($("#log").text(),"张三");"); //从test.html中取log元素中的text,应该为张三
}
@Test
public void testPrint() throws Exception {
run("print('hello js!');");
}
@Test
public void testNotEqualsNum() throws Exception {
run("assertNotEqualsNum(1,2);");
}
@Test
public void testEqualsNum() throws Exception {
run("assertEqualsNum(1,1);");
}
@Test
public void testEqualsStr() throws Exception {
run("assertEqualsStr("abc","abc");");
}
@Test
public void testNotEqualsStr() throws Exception {
run("assertNotEqualsNum(1,2);");
}
private void loadJS(String sourceName, String classpathURI) {
String js = null;
InputStream inputStream = null;
try {
inputStream = getClass().getResourceAsStream(classpathURI);
js = IOUtils.toString(inputStream, "UTF-8");//设置默认js文件编码为utf-8
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputStream);
}
cx.evaluateString(scope, js, sourceName, 1, null);
}
private String run(String js) throws Exception {
Object result = cx.evaluateString(scope, js, "run", 1, null);
return Context.toString(result);
}
private void waitSec(int sec) {
try {
Thread.sleep(1000 * sec);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} a、@BeforeClass时启动内嵌Jetty服务器来响应test.html的请求与/ajaxservice请求。
b、@Before时对Rhino进行初始化,加入一些预制js调试方法。
c、testJqueryAjax方法中用loadJs加载jquery与my.js。
d、调用window.location模拟浏览器显示页面。
e、调用myFunction发起Ajax请求,Jetty会在AjaxHandler中收到请求并响应json数据。
f、myFunction中会根据返回数据修改页面显示div(div id="log")
g、使用自定义的js方法assertEqualsStr来验证dom元素是否被修改正确
5、pom.xml
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.noahx.ajaxtest
ajax-test
1.0
org.mozilla
rhino
1.7R4
test
commons-io
commons-io
2.4
test
org.eclipse.jetty
jetty-server
8.1.10.v20130312
test
junit
junit
4.11
test
四、总结
可以用这样的方式单元测试js确实我也没有想到,大家也可以用这样方式来模拟页面行为获得动态页面数据。
源码下载:
http://sdrv.ms/10HUv7y
来源:oschina
链接:https://my.oschina.net/u/569848/blog/121347
最后
以上就是帅气奇异果为你收集整理的junit测试ajax,用Java(JUnit4)对JavaScript(含Ajax)脚本进行单元测试的全部内容,希望文章能够帮你解决junit测试ajax,用Java(JUnit4)对JavaScript(含Ajax)脚本进行单元测试所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复