`

easymock教程-运行时返回值或者异常

 
阅读更多

        前面的教程中,我们看到easymock可以通过expect方法来设定mock方法的返回值或者异常,但是注意这些案例中设置的返回值都是在调用被测试的类的方法前就已经确定下来的,即我们其实在测试类的代码运行前(实际是在EasyMock.replay()方法调用前)就已经"预知"了返回结果。

 

    但是在某些情况下,我们可能无法预知返回值,比如我们需要根据输入的参数值来决定返回什么,而这个参数可能无法在record阶段获得。因此在mock方法中我们无法在record阶段就决定应该返回什么。

 

    对于这种场景,easymock提供了IAnswer接口和andAnswer()方法来提供运行时决定返回值或者异常的机制。

 

    我们来看一个简单的例子:

    public class Business {
        
private Service service;

        
public void execute() {
            
int count = ramdonInt();
            
int result = service.execute(count);
        }


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


        
private int ramdonInt() {
            Random random 
= new Random();
            
return random.nextInt() / 10000;
        }

    }


    
public interface Service {
        
public int execute(int count);
    }

    在Business的execute()方法中,需要调用service.execute(int count)方法,而传入的参数count是需要运行时才能确定的,这里为了简单我们random了一个int来模拟这种情况。

 

    然后看测试案例

    @Test
    
public void testRuntimeReturn() {
        Business business 
= new Business();
        Service service 
= EasyMock.createMock(Service.class);
        business.setService(service);
        EasyMock.expect(service.execute(EasyMock.anyInt())).andAnswer(
new IAnswer<Integer>() {
            
public Integer answer() throws Throwable {
                Integer count 
= (Integer) EasyMock.getCurrentArguments()[0];
                
return count * 2;
            }

        }
);

        EasyMock.replay(service);
        business.execute();
        EasyMock.verify(service);
    }

    这里我们通过EasyMock.expect(service.execute(EasyMock.anyInt()))来接受任意值的count参数输入,andAnswer(new IAnswer<Integer>() {}) 让我们可以指定一个IAnswer的实现类来给出返回值。在这个IAnswer的实现类中,我们通过EasyMock.getCurrentArguments()[0]获取到service.execute()方法的第一个参数,然后简单的运用count*2规则给出返回值。这里的EasyMock.getCurrentArguments()方法可以获取到运行时的参数列表,不过注意这个方法对重构不够友好,如果参数列表发生变化则必须手工修改对象的获取参数的代码。

 

    下面是一个运行时抛出异常的例子,简单起见我们通过设置exception的message来在错误信息中传递运行时的count值。

   @Test
    
public void testRuntimeException() {
        Business business 
= new Business();
        Service service 
= EasyMock.createMock(Service.class);
        business.setService(service);
        EasyMock.expect(service.execute(EasyMock.anyInt())).andAnswer(
new IAnswer<Integer>() {
            
public Integer answer() throws Throwable {
                Integer count 
= (Integer) EasyMock.getCurrentArguments()[0];
                
throw new RuntimeException("count=" + count);
            }

        }
);

        EasyMock.replay(service);
        
try {
            business.execute();
            fail(
"should throw RuntimeException");
        }
 catch (RuntimeException e) {
            assertTrue(e.getMessage().indexOf(
"count="!= -1);
            
//get count from message
            EasyMock.verify(service);
        }

    }

    除了IAnswer接口外,easymock中还有另外一个方式可以完成类似的功能,就是使用andDelegate()方法,

    public class ServiceStub implements Service {
        
public int execute(int count) {
            
return count * 2;
        }

    }


    @Test
    
public void testRuntimeReturn() {
        Business business 
= new Business();
        Service service 
= EasyMock.createMock(Service.class);
        business.setService(service);
        EasyMock.expect(service.execute(EasyMock.anyInt())).andDelegateTo(
new ServiceStub());

        EasyMock.replay(service);
        business.execute();
        EasyMock.verify(service);
    }

    这里需要先创建一个Service类的实现类和一个实例,然后通过andDelegateTo()将这个stub的实例传进去,注意这里delegate进去的实例必须是mock对象接口相同。

 

    delegateTo方式实际上是我们手工创建了stub(mock和stub的概念及差别请参考本教程的"mock和stub"一文),这和我们使用easymock的初衷有所违背。而且当这个接口有众多方法时,创建这样一个stub会显得很痛苦,不如使用IAnswer方便直接。

 

分享到:
评论

相关推荐

    easymock详解教程

    #### 1.13 easymock教程-运行时返回值或者异常 在某些情况下,可能希望根据不同的条件返回不同的值或抛出不同的异常。easymock支持运行时动态改变返回值或异常。 - **定义返回值**:使用`andReturn`方法来定义方法...

    easymock教程.pdf

    ### 运行时返回值或者异常 * 使用easymock的andReturn方法可以指定返回值。 * 使用easymock的andThrow方法可以指定抛出异常。 ### 改变同一个方法调用的行为 * 使用easymock的andThen方法可以改变同一个方法调用...

    easymock教程

    ##### 1.13 运行时返回值或者异常 - **动态设定返回值**:在测试过程中,可以根据不同的条件设定不同的返回值。 - **模拟异常**:也可以设置某些方法调用时抛出异常。 ##### 1.14 改变同一个方法调用的行为 - **...

    easymock教程.zip

    这个“easymock教程.zip”包含了帮助你深入理解和使用Easymock的资源,特别是其中的“easymock教程.pdf”。下面将详细阐述Easymock的核心概念、功能以及如何使用它进行单元测试。 1. **什么是Easymock**: ...

    easymock-2.5.2工具 下载

    EasyMock的工作原理是,它允许开发者指定模拟对象的行为,例如方法调用的返回值、异常或者回调。在测试过程中,这些模拟对象会代替真实的依赖,从而使得测试更加可控。例如,你可以设置一个模拟数据库连接,在特定的...

    easymock-3.2.zip

    4. **所需jar包**:这是EasyMock运行所需的库文件。在Java项目中,你需要将这些jar包添加到类路径(classpath)中,以便在代码中引入并使用EasyMock的API。 使用EasyMock进行单元测试的基本流程如下: 1. **创建...

    easyMock.zip

    在阅读“easymock教程-easymock的典型使用 - 一个执着的程序员 - 博客频道 - CSDN.NET.html”这篇教程时,应重点关注如何创建和配置模拟对象,理解预设行为和验证的方法,以及如何将EasyMock与Junit结合使用。...

    easymock教程[归纳].pdf

    12. **运行时返回值或异常** - 在测试中,可以控制mock对象在特定调用时返回不同的值或抛出异常,模拟各种可能的运行情况。 13. **改变同一个方法调用的行为** - 在不同的调用中,Easymock允许为同一方法设定不同...

    EasyMock.NET-开源

    3. **配置行为**:通过调用`Expect`方法设置模拟对象的方法行为,包括返回值、异常处理等。 4. **启动录制**:开始记录模拟对象的行为,所有在这个阶段的行为都会被记录下来。 5. **执行测试代码**:在录制期间,...

    easymock2.4+EasyMock使用简明手册.pdf

    4. **动态mocking**:除了静态地设置期望,EasyMock 2.4还支持动态mocking,这意味着在运行时可以改变模拟对象的行为。 三、使用步骤 1. **创建模拟对象**:使用`EasyMock.createMock()`方法创建模拟对象。 2. **...

    EasyMock and PowerMock入门PPT

    2. 安全的重构支持,即使在运行时修改方法名或参数,测试也不会中断。 3. 支持返回值和异常的设定。 4. 支持检查方法调用的顺序。 缺点: - 要求Java 5.0或更高版本。 - 需要下载额外的扩展包以支持抽象类的模拟。 ...

    easyMock

    EasyMock支持动态mocking,这意味着可以在运行时改变模拟对象的行为。这在测试中非常有用,因为可以根据测试需求灵活地调整模拟对象的响应。 **4. 高级特性** - **回调**:使用`doAnswer()`方法,可以指定当方法被...

    EasyMock 架包

    例如,我们可以设置一个方法在被调用时返回一个特定值,或者在被调用一定次数后抛出异常。 在EasyMock 3.1版本中,引入了一些关键特性: 1. **清晰的API**:EasyMock提供了清晰且易于使用的API,使得设置和验证...

    EasyMock介绍和使用

    3. **复杂逻辑验证**:对于有复杂条件判断或流程控制的代码,EasyMock可以设置不同的调用顺序和返回值,以便全面检查各种可能的情况。 4. **减少环境影响**:在多线程环境中,模拟对象可以避免因并发问题导致的测试...

    EasyMock.jar

    8. **类型安全**:EasyMock 2.5.1版可能已经提供了类型安全的API,这使得在编写测试代码时能获得编译时的错误检查,减少运行时错误的可能性。 使用EasyMock进行单元测试可以帮助提高代码质量,减少回归错误,并使...

    easymock 3.0

    4. **回调方法**:除了预定义返回值,Easymock还支持使用`EasyMock.callback()`方法定义回调函数,使得mock对象的方法调用可以执行自定义逻辑。 5. **异常测试**:可以设置mock对象抛出预期的异常,以便测试错误...

    easyMock resource

    这时,我们可以使用EasyMock创建B的mock对象,设置其返回值或抛出异常,然后在JUnit测试中使用这个mock对象代替真实的B,从而专注于测试类A的行为。 在文件名称列表`testFromwork`中,可能包含了相关的测试代码示例...

    java easymock

    12. **运行时返回值或异常**: 在测试中,你可以控制模拟对象在特定条件下返回特定值,或者在方法调用时抛出异常。 13. **改变同一个方法调用的行为**: 有时,你可能希望同一个方法在不同的调用中有不同的行为,...

    5-Mock+EasyMock.rar

    这包括方法参数的匹配、返回值设定以及抛出异常的情况。 3. **验证调用**:测试完成后,使用`replay`和`verify`方法来检查Mock对象是否按照预期进行了方法调用。`replay`将Mock对象切换到执行模式,`verify`则检查...

    easymock 学习

    EasyMock 支持多种模拟行为,包括方法调用、返回值设置、异常抛出等。 ### 核心概念 1. **模拟对象(Mock Object)**:EasyMock 创建的模拟对象用于代替真实的依赖,可以预定义其行为和预期调用。 2. **期望...

Global site tag (gtag.js) - Google Analytics