junit测试ajax,用Java(JUnit4)对JavaScript(含Ajax)脚本进行单元测试

一、背景

因为原来采用过Rhino(JS解析引擎,新版JDK中也默认包含另外一个解析引擎)来在Java环境中解析JavaScript并运行其中的方法。最近看到有人在问题里提问,模拟Ajax请求的问题。所以就想看看有没有方法通过Rhino来实现Ajax请求的模拟。

二、分析

通过上网检索,发现可以采用Envjs,一个纯js方式在无浏览器环境下模拟浏览器的行为,并且与Rhino有集成。这样我就可以实现用Java来处理孤立js中的Ajax请求。

三、开发

1、项目目录结构

6c1555302777729326ca3efa0910d9ec.png

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">

ilog

需要测试的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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值