【问题标题】:EasyMock 3.0, mocking class throws java.lang.IllegalStateException: no last call on a mock availableEasyMock 3.0,模拟类抛出 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>

【问题讨论】:

    标签: easymock


    【解决方案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) 解决了问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-23
          • 2011-06-28
          • 1970-01-01
          • 2016-09-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多