`

easymock教程-mock的限制

阅读更多

    easymock并不是万能的,在使用easymock时有一些限制需要注意。

 

(1) Object方法的限制

    我们都知道java是一个单根继承体系,Object是所有类的基类。在Object类上有几个基本的方法,easymock是不能改变其行为的:equals(), hashCode()和toString()。

 

    即对于easymock创建的mock对象,其equals(), hashCode()和toString()三个方法的行为时已经固定了点,不能通过Easymock.expect()来指定这三个方法的行为,即使这三个方法是接口定义的一部分。

 

    我们来先看一个例子:

   public class Business {
        
private Service service;

        
public void execute() {
            System.out.println(
"service.toString() = " + service.toString());
            System.out.println(
"service.hashCode() = " + service.hashCode());
        }


        
public void setService(Service service) {
            
this.service = service;
        }

    }


    
private interface Service {

        
public String toString();

        
public int hashCode();
    }

    execute()方法将为我们打印出toString()和hashCode()方法的结果。

public class LimitationTest {

    
private Business      business;

    
private IMocksControl mocksControl;

    
private Service       service;

    @Before
    
public void init() {
        business 
= new Business();
        mocksControl 
= EasyMock.createStrictControl();
        service 
= mocksControl.createMock(Service.class);
        business.setService(service);
    }


    @Test
    
public void testDefaultBehavior() {
        business.execute();
    }


    @Test
    
public void testCustomizedBehavior() {

        EasyMock.expect(service.toString()).andReturn(
"Customized toString");
        EasyMock.expect(service.hashCode()).andReturn(
100000);
        mocksControl.replay();

        business.execute();
        mocksControl.verify();
    }

}

    测试案例testDefaultBehavior()将为我们打印出mock对象默认的行为,输出如下:

service.toString() = EasyMock for interface net.sourcesky.study.easymock.tutorial.LimitationTest$Service
service.hashCode() = 26208195

 

    可见easymock内部已经做好了toString()和hashCode()实现。

 

    在测试案例testCustomizedBehavior()中,我们试图通过EasyMock.expect()来指定toString()和hashCode()的行为,但是运行时遭遇错误:

 

    java.lang.IllegalStateException: no last call on a mock available
 at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:521)
 at org.easymock.EasyMock.expect(EasyMock.java:499)
 at net.sourcesky.study.easymock.tutorial.LimitationTest.testCustomizedBehavior(LimitationTest.java:51)
 ...

 

    从"no last call on a mock available"的描述上看,easymock根本没有把对toString()方法的调用记录(record)下来作为一个对mock对象的调用。

 

    因此,在使用mock对象时,请注意equals(), hashCode()和toString()三个方法无法更改其行为。

 

(2) class mock的限制

 

    相对于interface mock,class mock下easymock限制更多,除了上面谈到的equals(), hashCode()和toString()三个方法外,还有以下限制:

    1. final 方法不能被mock
    2. private 方法不能对mock

 

(3) 静态方法

    对于静态方法,easymock也无法mock其行为。

 

    由于这个限制,当被测试类中有静态方法调用时,典型如单例方法调用,lookup方式的依赖查找,easymock就会力不从心。从这个角度上,推荐尽量使用IOC 控制反转/ DI依赖注入的方式来实现依赖的获取,而不要使用lookup的主动查找方式。

 

    实际开发中,当发现有因为静态方法的限制从而导致easymock无法mock我们期望的行为,造成测试案例"不好写",“写不下去”时,请换个角度思考:为什么要用静态方法?可不可以改成注入?

 

(4) 解决的方法

 

    如果由于某些原因必须使用静态方法或者定制final, private方法的行为,则可以考虑搭配其他mock框架来完成功能。

 

    以静态方法方法为例,一个典型的使用范例是:使用jmockit来定制静态方法的行为,指定其返回easymock创建的mock对象,然后使用easymock的标准方式定制这个mock对象的行为。

 

分享到:
评论

相关推荐

    easymock详解教程

    #### 1.7 easymock教程-mock的限制 虽然easymock提供了强大的功能,但在某些情况下也存在一定的限制: - **final方法**:无法模拟final修饰的方法。 - **静态方法**:无法直接模拟静态方法,但可以通过模拟包含...

    easymock教程.pdf

    easymock教程 easymock是一种流行的mocking框架,用于单元测试中模拟依赖对象的行为。下面是关于easymock的详细知识点: ### easymock的基本概念 * Mock对象:是一种虚拟对象,模拟真实对象的行为,用于单元测试...

    easymock教程

    ##### 1.7 Mock的限制 - **构造函数调用**:Mock对象无法模拟构造函数调用。 - **静态方法**:默认情况下,Easymock不支持模拟静态方法。可以通过第三方库如PowerMock来扩展Easymock的功能以支持静态方法的模拟。 -...

    easymock教程[归纳].pdf

    本教程详细介绍了Easymock的各种特性和使用方法,旨在帮助软件开发人员掌握这一工具。 1. **Mock和Stub的概念** - Mock对象是用于代替真实对象的虚拟对象,它在测试中按照预设的规则来响应调用,帮助验证方法是否...

    EasyMock介绍及安装方法

    EasyMock 可以 mock 接口和 java 类,但是 class mocking 有一些限制: 不能 mock 类的 final 方法。如果 final 方法被调用,则只能执行原有的正常代码。 不能 mock 类的 static 方法。同样如果 private 方法被调用...

    轻仿即刻数据来自easymock的服务

    "轻仿即刻数据来自easymock的服务"这个项目就是利用了EasyMock这一强大的Mock数据生成平台,为开发工作提供了便捷的数据支持。EasyMock是一个开源的Java库,它允许开发者创建模拟对象来测试他们的代码,而无需实际...

    PowerMock\EasyMock的相关资料和文档

    EasyMock是一个强大的模拟框架,它允许开发者创建预期的交互(mock objects)并验证这些对象是否按照预期的方式与实际代码进行交互。在EasyMock中,你可以定义mock对象的方法调用行为,比如返回特定值或抛出异常。这...

    java easymock

    尽管强大,但EasyMock有一些限制。例如,它不能模拟final方法,静态方法,或者构造函数。对于这些情况,可能需要使用其他的模拟框架,如PowerMock。 7. **Strict和Nice Mocks**: Strict Mocks要求所有预定义的...

    GMock——groovy下的mock工具

    - **JUnit**:是一个流行的 Java 单元测试框架,虽然不直接提供 mock 功能,但可以与 EasyMock 或 Mockito 等工具结合使用。 - **EasyMock**:是另一个 Java 的模拟库,提供简单的 API 来创建和管理 mock 对象,但它...

    基于Java Agent实现的自测,联调Mock利器.zip

    传统Mock框架如Mockito、EasyMock等,它们通常是在运行时创建和配置Mock对象。而基于Java Agent的Mock工具可能是在类加载时即完成Mock对象的替换,这样可以对无法直接Mock的静态方法或final类进行Mock,增强了Mock的...

    mockito单元测试

    与传统的Mock工具(如EasyMock)相比,Mockito更加直观且易于使用。Mockito的一个显著特点是支持对复杂场景的模拟,如模拟静态方法、构造函数等,这对于构建大型系统尤为重要。 ##### 2.2 新特性与限制 在Mockito ...

    powermock-examples-documentationexamples-1.4.10.zip

    EasyMock和Mockito是两个流行的Mocking框架,PowerMock在此基础上增加了对更多不可mock对象的支持,提高了测试的灵活性。 3. **GWT (Google Web Toolkit)**: GWT 是一个开源的Java开发框架,用于构建和部署...

    PowerMock+Mockito-junit测试套件1.6.3版本

    PowerMock是一个扩展了其他Mocking框架(如EasyMock和Mockito)的库,它允许开发者对静态方法、构造函数、final类和方法、私有方法以及删除静态初始化器进行模拟和mock。在传统测试框架中,这些通常是难以或无法测试...

    powermock实战手册

    虽然PowerMock提供了强大的功能,但也有一些需要注意的限制,比如性能开销较大,可能会导致测试更加复杂,且不易于理解和维护。因此,使用PowerMock时应谨慎,尽可能遵循“最小侵入性原则”,只在确实需要时才使用。...

    可重复使用文件保存

    2. **预定义行为**:接着,通过`expect()`方法设置预期的调用,如`expect(mockObject.someMethod()).andReturn(someValue)`,这定义了当模拟对象的`someMethod()`被调用时应返回`someValue`。 3. **启动验证**:在...

    SampleEasymockConstructor:如何在测试运行时用参数替换具有构造函数的类的新实例的示例

    在Java中,由于私有方法的访问限制,它们不能直接被外部类调用。然而,对于测试,有时我们需要检查私有方法的行为。EasyMock虽然主要设计用于公共方法的模拟,但它可以通过`PowerMock`扩展来处理这种情况。`...

    PowerMock.zip

    PowerMock 是一个强大的Java单元测试框架的扩展,它允许开发者模拟静态方法、构造函数、final 类、enum 和私有方法,这些都是传统单元测试工具如JUnit和EasyMock无法处理的。这个压缩包“PowerMock.zip”可能包含...

    junitTesting

    6. **超时测试**:可以使用`@Test(timeout =毫秒数)`注解来限制测试方法的执行时间,如果超过这个时间仍未完成,测试将失败。 7. **假对象和Mocking**:在JUnit测试中,经常需要模拟(mock)或桩(stub)其他依赖...

Global site tag (gtag.js) - Google Analytics