EasyMock 3.0,模拟类抛出 java.lang.IllegalStateException: no last call on a mock available

Posted

技术标签:

【中文标题】EasyMock 3.0,模拟类抛出 java.lang.IllegalStateException: no last call on a mock available【英文标题】:EasyMock 3.0, mocking class throws java.lang.IllegalStateException: no last call on a mock available 【发布时间】:2011-03-30 12:39:10 【问题描述】:

运行以下单元测试会引发异常:java.lang.IllegalStateException: no last call on a mock available


import org.easymock.*;
import org.junit.*;

public class MyTest 

    @Test
    public void testWithClass() 
        Thread threadMock = EasyMock.createMock(Thread.class);
        EasyMock.expect(threadMock.isAlive()).andReturn(true);
    

我不确定自己做错了什么,并且在网上找不到任何好的示例。你如何使用 EasyMock 3.0 模拟一个类。上面的单元测试有什么问题?任何帮助将不胜感激。

我的项目包含以下 maven 依赖项

<dependency>
   <groupId>org.easymock</groupId>
   <artifactId>easymock</artifactId>
   <version>3.0</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib-nodep</artifactId>
   <version>2.2</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>org.objenesis</groupId>
   <artifactId>objenesis</artifactId>
   <version>1.2</version>
   <scope>test</scope>
</dependency>

【问题讨论】:

【参考方案1】:

这个异常的原因是Thread#isAlive()是一个final方法,但是EasyMock不支持对final方法的mock。因此,在 EasyMock.expect(...) 中出现的对该方法的调用不被视为“模拟调用”。

要模拟最终方法,您需要一个不同的模拟工具,例如 JMockit(我开发的):

public void testMockingFinalMethod(@Mocked("isAlive") Thread mock)

    new Expectations()
    
        mock.isAlive(); result = true;
    ;

    assertTrue(mock.isAlive());

在一般情况下,模拟 API 实际上并不要求明确指定要模拟的方法。不过,Thread 类是一个棘手的类。

【讨论】:

【参考方案2】:

您的测试方法看起来不错,只是您还没有准备您创建的模拟对象。这必须使用

EasyMock.replay(mockObject1, mockObject2, ...);

这将准备模拟对象,使其成为运行 JUnit 时使用的对象。您的依赖项也没有问题。

此外,您似乎没有调用您在此处进行单元测试的 实际方法。通常,编写测试方法的方法是使用模拟库编写 JUnit 方法 (例如 EasyMock 和 PowerMock)仅当存在超出测试方法上下文的外部对象时,然后重放所有模拟对象(准备模拟以替代测试中的真实业务对象)。之后,您调用您尝试测试的实际方法,并使用org.junit.Assert.assertXXX() 方法验证功能。

【讨论】:

【参考方案3】:

我在一个测试用例或套件中多次调用 EasyMock.replay(mock) 导致此问题,并且在每个测试用例或套件之间调用 EasyMock.reset(mock) 解决了问题。

【讨论】:

以上是关于EasyMock 3.0,模拟类抛出 java.lang.IllegalStateException: no last call on a mock available的主要内容,如果未能解决你的问题,请参考以下文章

Powermock 不断为 ScriptEngineManager 抛出错误

期望任何东西作为参数来模拟使用 EasyMock

模拟对象测试——EasyMock

如何使用 JUnit、EasyMock 或 PowerMock 模拟静态最终变量

是否可以使用 EasyMock 创建一个实现多个接口的模拟对象?

Easymock:如何在不可见的情况下模拟受保护方法的调用