Struts测试之Mock Object测试

Struts测试之Mock Object测试

以下内容引自 http://www.xgdown.com/article/239/47289_1.htm

使用Mock Object进行测试,主要是用来模拟那些在应用中不容易构造(如HttpServletRequest必须在Servlet容器中才能构造出来)或者比较复杂的对象(如JDBC中的ResultSet对象)从而使测试顺利进行的工具。

JMock

简介

请访问 http://www.jmock.org

准备

1.        获取 J2SDK

2.        获取 JUnit V3.8.1 (从 http://www.junit.org 获取开发包);

3.        获取 JMock V1.0 (从 http://www.jmock.org 获取 JMock 开发包)。

4.        为了开发方便,建议使用一个好 IDE 。以下例子中的代码均是在 Eclipse V3.0 环境下进行的调试。

例子一

以下是一个简单例子,代码如下:

package test1;

 

import org.jmock.*;

import javax.servlet.http.*;

 

public class MockRequestTest extends MockObjectTestCase{

    public void testMockRequest1(){

       // 构造一个 Mock 对象

        Mock mock = new Mock(HttpServletRequest.class);

       

        // 设置要执行的操作,以下设置表示要调用一次 HttpServletRequest 对象的

        //getParameter 方法,传递的参数是 "name", 期望的返回是 "kongxx"

        mock.expects(once()).method("getParameter").with(eq("name")).will(returnValue("kongxx"));

       

        // 根据 Mock 对象获取一个 HttpServletRequest 对象

        HttpServletRequest request = (HttpServletRequest)mock.proxy();

       

        // 断言调用结果

        assertEquals("kongxx" ,request.getParameter("name"));       

    }

    public void testMockRequest2(){

       // 构造一个 Mock 对象

        Mock mock = new Mock(HttpServletRequest.class);

       

        // 设置要执行的操作,以下设置表示要调用一次 HttpServletRequest 对象的

        //getParameter 方法,传递的参数是 "name", 期望的返回是 "kongxx"

        mock.expects(once()).method("getParameter").with(eq("name")).will(returnValue("kongxx"));

       

        // 根据 Mock 对象获取一个 HttpServletRequest 对象

        HttpServletRequest request = (HttpServletRequest)mock.proxy();

       

        // 调用 HttpServletRequest 对象的方法

        request.getParameter("name");       

       

        // 验证执行结果

        mock.verify();

    }

}

编译并将其当做一个 Test Case 运行,会发现两个测试方法均测试成功。

例子二

MyClass 需要测试的类,提供了两个方法 getName getPassword ,都使用 HttpServletRequest 作为输入参数并返回从 HttpServletRequest 中取得的参数,具体代码如下:

package test2;

 

import javax.servlet.http.*;

 

public class MyClass {

    public String getName(HttpServletRequest request) {

       return request.getParameter("name");

    }

   

    public String getPassword(HttpServletRequest request) {

       return request.getParameter("password");

    }

}

TestMyClass 测试类,其中构造了一个假的 HttpServletRequest 对象,用来测试 MyClass 中的 getName getPassword 方法,代码如下:

package test2;

 

import org.jmock.*;

import javax.servlet.http.*;

 

public class TestMyClass extends MockObjectTestCase{

    private MyClass myclass ;

    private Mock mockRequest ;

    private HttpServletRequest request ;

   

    public void setUp() {      

       myclass = new MyClass();

      

       // 构造一个 Mock 对象

       mockRequest = new Mock(HttpServletRequest.class);

      

       // 根据 Mock 对象获取一个 HttpServletRequest 对象

       request = (HttpServletRequest)mockRequest.proxy();

    }

    public void tearDown() {

       //TODO

    }

    public void testGetName(){

       // 设置要执行的操作,以下设置表示要调用一次 HttpServletRequest 对象的

        //getParameter 方法,传递的参数是 "name", 期望的返回是 "kongxx"     

       mockRequest.expects(atLeastOnce()).method("getParameter").with(eq("name")).will(returnValue("kongxx"));

      

       assertNotNull(myclass.getName(request));

        assertEquals("kongxx" ,myclass.getName(request));      

    }

    public void testGetPassword(){

       // 设置要执行的操作,以下设置表示要调用一次 HttpServletRequest 对象的

        //getParameter 方法,传递的参数是 "password", 期望的返回是 "123456789"  

        mockRequest.expects(atLeastOnce()).method("getParameter").with(eq("password")).will(returnValue("123456789"));

      

       assertNotNull(myclass.getPassword(request));

        assertEquals("123456789" ,myclass.getPassword(request));

    }

}

编译并将其当做一个 Test Case 运行,会发现两个测试方法均测试成功。

 

EasyMock

简介

请访问 http://www.easymock.org

准备

1.         获取 J2SDK

2.         获取 JUnit V3.8.1 (从 http://www.junit.org 获取开发包);

3.         获取 EasyMock V1.1 (从 http://www.easymock.org 获取 EasyMock 开发包)。

4.         为了开发方便,建议使用一个好 IDE 。以下例子中的代码均是在 Eclipse V3.0 环境下进行的调试。

例子一

以下是一个简单例子,为了方便对比,这里重新实现了 JMock 例子一 ,代码如下:

package test1;

 

import org.easymock.*;

import junit.framework.*;

import javax.servlet.http.*;

 

public class MockRequestTest extends TestCase{

    private MockControl control;

    private HttpServletRequest mockRequest;

 

    public void testMockRequest(){

       // 创建一个 Mock HttpServletRequest MockControl 对象

       control = MockControl.createControl(HttpServletRequest.class);

      

       // 获取一个 Mock HttpServletRequest 对象

       mockRequest = (HttpServletRequest) control.getMock();

          

       // 设置期望调用的 Mock HttpServletRequest 对象的方法

       mockRequest.getParameter("name");

      

       // 设置调用方法期望的返回值,并指定调用次数

       // 以下后两个参数表示最少调用一次,最多调用一次

       control.setReturnValue("kongxx" ,1 ,1);  

      

       // 设置 Mock HttpServletRequest 的状态,

       // 表示此 Mock HttpServletRequest 对象可以被使用

       control.replay();

      

       // 使用断言检查调用

       assertEquals("kongxx",mockRequest.getParameter("name"));

      

       // 验证期望的调用

       control.verify();

    }

}

编译并将其当做一个 Test Case 运行,会发现两个测试方法均测试成功。

例子二

同例子一样,对 JMock 例子二 重新实现产生了 EasyMock 的例子二。

需要测试的类代码如下:

package test2;

 

import javax.servlet.http.*;

 

public class MyClass {

    public String getName(HttpServletRequest request) {

       return request.getParameter("name");

    }

   

    public String getPassword(HttpServletRequest request) {

       return request.getParameter("password");

    }

}

测试类代码如下:

package test2;

 

import org.easymock.*;

import junit.framework.*;

import javax.servlet.http.*;

 

public class TestMyClass extends TestCase{

   

    private MockControl control;

    private HttpServletRequest mockRequest;

    private MyClass myclass ;

   

    public void setUp() {      

       myclass = new MyClass();

      

       // 创建一个 Mock HttpServletRequest MockControl 对象

       control = MockControl.createControl(HttpServletRequest.class);

      

       // 获取一个 Mock HttpServletRequest 对象

       mockRequest = (HttpServletRequest) control.getMock();      

    }

    public void tearDown() {

       //TODO

    }

    public void testGetName(){

       // 设置期望调用的 Mock HttpServletRequest 对象的方法

       mockRequest.getParameter("name");

      

       // 设置调用方法期望的返回值,并指定调用次数

       // 以下后两个参数表示最少调用一次,最多调用一次

       control.setReturnValue("kongxx" ,1 ,2);  

      

       // 设置 Mock HttpServletRequest 的状态,

       // 表示此 Mock HttpServletRequest 对象可以被使用

       control.replay();

      

       // 使用断言检查调用

       assertNotNull(myclass.getName(mockRequest));

       assertEquals("kongxx",myclass.getName(mockRequest));

      

       // 验证期望的调用

       control.verify();   

    }

    public void testGetPassword(){

       // 设置期望调用的 Mock HttpServletRequest 对象的方法

       mockRequest.getParameter("password");

      

       // 设置调用方法期望的返回值,并指定调用次数

       // 以下后两个参数表示最少调用一次,最多调用一次

       control.setReturnValue("kongxx" ,1,2);

      

       // 设置 Mock HttpServletRequest 的状态,

       // 表示此 Mock HttpServletRequest 对象可以被使用

       control.replay();

      

       // 使用断言检查调用

       assertNotNull(myclass.getPassword(mockRequest));

       assertEquals("kongxx",myclass.getPassword(mockRequest));

      

       // 验证期望的调用

       control.verify();  

    }

}

编译并将其当做一个 Test Case 运行,会发现两个测试方法均测试成功。


独立测试就是单独测试一个类或方法里的代码,而不测试里面调用的其他类或方法的代码。即假定调用的其他类或方法都正常执行。

  • 使用Mock Object的场合
    1. 实际对象的行为还不确定。
    2. 实际的对象创建和初始化非常复杂。
    3. 实际对象中存在很难执行到的行为(如网络异常等)。
    4. 实际的对象运行起来非常的慢。
    5. 实际对象是用户界面程序。
    6. 实际对象还没有编写,只有接口等。
  • 简单分析用Mock Object的原因

    假定我们有对象A,它内部频繁调用了B中的方法。但是除了调用B的部分还存在自己的逻辑代码。这时,我们只想写A的单体测试,而不想测试B(因为B可能还没编写,只写了实现的接口或者B运行太慢了影响我们的测试效率)。这样的话,我们就需要创建B的Mock对象。

    换言之,我们现在不关心B,我们假定B的行为都能正常运行。我们的目标是假定B运行正常的情况下,来对A进行单体测试。

    Mock对象就是我们先不用关心的对象,但是我们的关注对象对它有调用,所以我们给关注对象准备个假货让它用。

     

  • posted on 2006-02-17 09:02 扭转乾坤 阅读(531) 评论(0)  编辑  收藏 所属分类: Struts相关


    只有注册用户登录后才能发表评论。


    网站导航:
     
    <2024年11月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    1234567

    导航

    统计

    常用链接

    留言簿(2)

    随笔分类(31)

    随笔档案(30)

    文章分类(32)

    文章档案(33)

    相册

    PHP小站-首页

    搜索

    积分与排名

    最新评论

    阅读排行榜

    评论排行榜