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 抛出错误
如何使用 JUnit、EasyMock 或 PowerMock 模拟静态最终变量