EasyMock 3.0,模拟类抛出 java.lang.IllegalStateException:没有对可用模拟的最后调用

发布于 2024-09-14 21:34:28 字数 1097 浏览 9 评论 0原文

运行以下单元测试会引发异常: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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北斗星光 2024-09-21 21:34:28

出现这个异常的原因是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 类是一个棘手的类。

The reason for this exception is that Thread#isAlive() is a final method, but EasyMock does not support the mocking of final methods. So, the call to this method which appears inside EasyMock.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):

public void testMockingFinalMethod(@Mocked("isAlive") Thread mock)
{
    new Expectations()
    {{
        mock.isAlive(); result = true;
    }};

    assertTrue(mock.isAlive());
}

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.

你的往事 2024-09-21 21:34:28

您的测试方法看起来不错,只是您尚未准备您创建的模拟对象。这必须使用以下命令来完成:

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

这将准备模拟对象,以便它将在运行 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

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

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.

会傲 2024-09-21 21:34:28

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

I had multiple calls to EasyMock.replay(mock) within one test case or suite causing this issue, and calling EasyMock.reset(mock) between each solved the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文