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

问题描述 投票:22回答:3

运行以下单元测试将引发异常: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>
easymock
3个回答
19
投票

发生此异常的原因是Thread#isAlive()final方法,但EasyMock不支持模拟最终方法。因此,对在EasyMock.expect(...)中出现的此方法的调用不会被视为“对模拟的调用”。

要模拟最终方法,您将需要其他模拟工具,例如JMockit(由我开发):

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

    assertTrue(mock.isAlive());
}

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


11
投票

您的测试方法看起来不错,但您还没有prepared已创建的模拟对象。这必须使用

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

这将准备模拟对象,以便在运行JUnit时使用该对象。您的依存关系也没有问题。

而且,您似乎没有在这里进行单元测试的调用actual method。通常,编写测试方法的方法是使用模拟库编写JUnit方法。(例如EasyMock和PowerMock)仅在测试方法上下文之外有外部对象时,然后重播所有模拟对象(这将准备模拟以替代测试中的实际业务对象)。之后,调用您要测试的实际方法,并使用org.junit.Assert.assertXXX()方法验证功能。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.