EasyMock 3.0,模拟类抛出 java.lang.IllegalStateException:没有对可用模拟的最后调用
运行以下单元测试会引发异常:java.lang.IllegalStateException:没有对可用的模拟进行最后一次调用
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>
Running the following unit test throws the exception: 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);
}
}
I am not sure what I am doing wrong and can not find any good examples on the web. How do you mock a class using EasyMock 3.0. What is wrong with the above unit test? Any help would be greatly appreciated.
My project includes the following maven dependencies
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
出现这个异常的原因是
Thread#isAlive()
是一个final
方法,但是EasyMock不支持final方法的mock。因此,出现在EasyMock.expect(...)
中的对该方法的调用不会被视为“对模拟的调用”。要模拟最终方法,您需要不同的模拟工具,例如 JMockit(我开发的):
在一般情况下,模拟 API 实际上并不要求显式指定要模拟的方法。不过,
Thread
类是一个棘手的类。The reason for this exception is that
Thread#isAlive()
is afinal
method, but EasyMock does not support the mocking of final methods. So, the call to this method which appears insideEasyMock.expect(...)
is not seen as a "call on a mock".To mock final methods you would need a different mocking tool, such as JMockit (which I develop):
The mocking API doesn't actually require that methods to be mocked are specified explicitly, in the general case. The
Thread
class is a tricky one, though.您的测试方法看起来不错,只是您尚未准备您创建的模拟对象。这必须使用以下命令来完成:
这将准备模拟对象,以便它将在运行 JUnit 时使用。您的依赖关系也没有问题。
另外,您似乎没有调用您在此处进行单元测试的实际方法。通常,编写测试方法的方法是使用模拟库编写 JUnit 方法
(例如 EasyMock 和 PowerMock)仅当存在超出测试方法上下文的外部对象时,然后重放所有模拟对象(准备模拟来替换测试中的真实业务对象)。之后,您调用要测试的实际方法,并使用 org.junit.Assert.assertXXX() 方法验证功能。
Your test method looks fine, except that you have not prepared the mock object you have created. This has to be done using
This will prepare the mocked object so that it is the one which will be used on running your JUnit. No issues with your dependencies as well.
Also, you don't seem to be calling the actual method which you are unit-testing here. Usually, the way to write a test method would be to write a JUnit method, using mocking libs
(such as EasyMock and PowerMock) ONLY when there are external objects beyond the test method context, and then replaying all the mocked objects (which prepares the mocks to substitute for the real business objects in the test). After that, you call the actual method you are trying to test, and validate the functionality using
org.junit.Assert.assertXXX()
methods.我在一个测试用例或套件中多次调用
EasyMock.replay(mock)
导致了此问题,并且在每次调用之间调用EasyMock.reset(mock)
解决了问题。I had multiple calls to
EasyMock.replay(mock)
within one test case or suite causing this issue, and callingEasyMock.reset(mock)
between each solved the problem.