Mock objects(简称mock)非常适合把部分代码逻辑的测试同其他代码隔离开来,它替换了测试中与你的方法协作的对象,从而提供了隔离层。从这个意义来说,它跟stub类似。可是,相似之处也仅限于此。Mock不实现任何逻辑:它们只是提供了一种使测试能控制仿造类的所有业务逻辑方法行为的方法的空壳。
EasyMock 是一套通过简单的方法对于指定的接口或类生成 Mock 对象的类库,它能利用对接口或类的模拟来辅助单元测试。
例子:
SampleSevlet.java(用于判断session中是否存在authenticated对象)
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class SampleServlet extends HttpServlet {
public boolean isAuthenticated(HttpServletRequest request){
HttpSession session = request.getSession();
if(session == null){
return false;
}
String authenticationAttribute = (String)session.getAttribute("authenticated");
return Boolean.valueOf(authenticationAttribute).booleanValue();
}
}
测试类:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import junit.framework.TestCase;
import org.easymock.MockControl;
public class SampleServletTest extends TestCase{
private SampleServlet servlet;
private MockControl mockControlServlet;
private HttpServletRequest request;
private MockControl mockControlSession;
private HttpSession session;
/**
* taseCase启动时加载
*/
@Override
protected void setUp() throws Exception {
servlet = new SampleServlet();
/*
* EasyMock通过为mock创建动态代理来工作的
* 动态代理是通过MockControl控制对象来控制的
*/
mockControlServlet = MockControl.createControl(HttpServletRequest.class);
request = (HttpServletRequest)mockControlServlet.getMock();
mockControlSession = MockControl.createControl(HttpSession.class);
session = (HttpSession)mockControlSession.getMock();
}
/**
* taseCase执行结束时调用
*/
@Override
protected void tearDown() throws Exception {
/**
* 效验mock方法是否被执行,若有一个未执行,则报错
* 如果未给某个mock方法定义任何行为,但是没有被调用到,则报错
*/
mockControlServlet.verify();
mockControlSession.verify();
}
public void testIsAuthenticatedAuthenticated(){
/**
* (1行)告诉 HttpServletRequest mock object,当getSession被调用
* (2行)该方法返回一个session
*/
request.getSession();
mockControlServlet.setReturnValue(session);
session.getAttribute("authenticated");
mockControlSession.setReturnValue("true");
//replay 激活mock
mockControlServlet.replay();
mockControlSession.replay();
assertTrue(servlet.isAuthenticated(request));
}
public void testIsAuthenticatedNotAuthenticated(){
request.getSession();
mockControlServlet.setReturnValue(session);
session.getAttribute("authenticated");
mockControlSession.setReturnValue(null);
mockControlServlet.replay();
mockControlSession.replay();
assertFalse(servlet.isAuthenticated(request));
}
public void testIsAuthenticatedNoSession(){
request.getSession();
mockControlServlet.setReturnValue(null);
mockControlServlet.replay();
mockControlSession.replay();
assertFalse(servlet.isAuthenticated(request));
}
}
Cactus是用来对服务端java代码进行单元测试的开源框架,是运行在容器内的
对SampleServlet.java测试的代码:
import org.apache.cactus.ServletTestCase;
import org.apache.cactus.WebRequest;
import com.doone.util.container.SampleServlet;
public class SampleServletCactusTest extends ServletTestCase{
private SampleServlet servlet;
protected void setUp(){
servlet = new SampleServlet();
}
public void testIsAuthenticatedAuthenticated(){
//cactus框架把容器对象提供给测试
session.setAttribute("authenticated","true");
assertTrue(servlet.isAuthenticated(request));
}
public void testIsAuthenticatedNotAuthenticated(){
assertFalse(servlet.isAuthenticated(request));
}
public void beginIsAuthenticatedNoSession(WebRequest request){
request.setAutomaticSession(false);
}
public void testIsAuthenticatedNoSession(){
assertFalse(servlet.isAuthenticated(request));
}
}
由于cactus是运行在容器内的,所以:
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.cactus.extension.jetty.JettyTestSetup;
public class TestAllWithJetty {
public static Test suite(){
//cactus测试的web应用环境所运行的上下文
System.setProperty("cactus.contextURL","http://localhost:8080/oohla");
TestSuite suite = new TestSuite();
suite.addTestSuite(SampleServletCactusTest.class);
//在测试执行前启动jetty并在测试结束后终止jetty
return new JettyTestSetup(suite);
}
}
1.Servlet(AdminServlet.java)
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class AdminServlet extends HttpServlet {
private static final Log log = LogFactory.getLog(AdminServlet.class);
private static final String COMMAND_PARAM = "command";
//校验请求参数command是否存在
public String getCommand(HttpServletRequest request)
throws ServletException{
String command = request.getParameter(COMMAND_PARAM);
if(command == null){
throw new ServletException("Messing parameter" + COMMAND_PARAM );
}
return command;
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String results = getCommand(request);
request.setAttribute("result",results);
log.info(results);
} catch (Exception e) {
throw new ServletException("Faild to execute command",e);
}
}
}
2.测试类(AdminServletTest.java)
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import com.mockobjects.dynamic.C;
import com.mockobjects.dynamic.Mock;
public class AdminServletTest extends TestCase {
AdminServlet servlet;
private Mock mockRequest;
private HttpServletRequest request;
private Mock mockResponse;
private HttpServletResponse response;
@Override
protected void setUp() throws Exception {
servlet = new AdminServlet();
mockRequest = new Mock(HttpServletRequest.class);
request = (HttpServletRequest)mockRequest.proxy();
mockResponse = new Mock(HttpServletResponse.class);
response = (HttpServletResponse)mockResponse.proxy();
}
@Override
protected void tearDown() throws Exception {
//mock objects校验设置的预期和你为之定义行为的方法被调用
mockRequest.verify();
}
public void testDoGet() throws ServletException, IOException{
mockRequest.expectAndReturn("getParameter","command","SELECT...");
mockRequest.expect("setAttribute",C.args(C.eq("result"),C.eq("SELECT...")));
servlet.doGet(request, response);
}
}
1. Servlet(6.1中AdminServlet.java)
2.测试类(AdminServletCactusTest.java)
import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.cactus.ServletTestCase;
import org.apache.cactus.WebRequest;
public class AdminServletCactusTest extends ServletTestCase{
private AdminServlet adminServlet;
//添加请求参数command
public void beginDoGet(WebRequest request){
request.addParameter("command","SELECT...");
}
//测试运行之前加载
@Override
protected void setUp() throws Exception {
adminServlet = new AdminServlet();
}
//测试doGet方法
public void testDoGet(){
try {
adminServlet.doGet(super.request, response);
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//断言得到的result参数为SELECT...
assertEquals("SELECT...",request.getAttribute("result"));
}
}