首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java Easymock抱怨"java.lang.IllegalStateException: void method不能返回值“或”没有最后一个可用的mock调用“。

Java Easymock抱怨"java.lang.IllegalStateException: void method不能返回值“或”没有最后一个可用的mock调用“。
EN

Stack Overflow用户
提问于 2012-04-11 01:00:39
回答 1查看 10.2K关注 0票数 2

我们使用EasyMock在Eclipse中对我们的Java应用程序进行JUnit测试。使用与下面类似的代码,我们发现了一个奇怪的行为:当运行完整的测试套件(Eclipse Project -> Run as -> JUnit)时,一个测试用例会重复失败。然而,当它独立运行时,它工作得很好。

接口:

代码语言:javascript
复制
package de.zefiro.java.easymockexception;

public interface Fruit {
    public String fall();
}

测试类:

代码语言:javascript
复制
package de.zefiro.java.easymockexception;

import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.junit.Assert.assertTrue;

import org.junit.BeforeClass;
import org.junit.Test;

public class Newton {
    private static final Fruit APPLE = createNiceMock(Fruit.class);

    @BeforeClass
    public static void SetUpClass() {
        expect(APPLE.fall()).andReturn("Targeting HEAD").anyTimes();
        replay(APPLE);
    }

    @Test
    public void testGravity() {
        String target = APPLE.fall();
        assertTrue("Missed", target.contains("HEAD"));
    }
}

测试套件:

代码语言:javascript
复制
package de.zefiro.java.easymockexception;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(value = Suite.class)
@SuiteClasses( { Newton.class } )
public class ScienceTests { }

在Eclipse项目上运行所有测试-即ScienceTests调用牛顿以及直接调用牛顿-在上面的小示例中产生了这个异常:

代码语言:javascript
复制
java.lang.IllegalStateException: no last call on a mock available
at org.easymock.Easymock.getControlForLastCall(EasyMock.java:175)

有一个similar question here,但它似乎是无关的。

在我们的实际测试代码中(更大的类,但主要参与者与精简后的示例相同)出现以下异常:

代码语言:javascript
复制
java.lang.IllegalStateException: void method cannot return a value
at org.easymock.internal.MocksControl.andReturn(MocksControl.java:101)

我在谷歌和StackOverflow上都没有找到答案,但现在我自己找到了答案,所以本着answering your own questions的精神,我将把我的发现发布在下面。值得一提的是我找到的这篇文章,尽管它在这个特殊的案例中对我没有帮助:EasyMock Cause-Effect Exception Mapping

EN

回答 1

Stack Overflow用户

发布于 2012-04-11 01:08:09

把断点放在初始化苹果和SetUpClass()的行上,我注意到苹果只被调用一次,而SetUpClass被调用两次。这是因为对牛顿的第一个引用创建了类并运行静态初始化器,但是JUnit在每次运行测试时都会调用@BeforeClass。在这种情况下,测试运行两次:一次作为普通调用,另一次作为测试套件的一部分。

我不想更改逻辑(即不使用static),而是将static @BeforeClass更改为静态初始化块:

代码语言:javascript
复制
public class Newton {

    [...]

    static {
        expect(APPLE.fall()).andReturn("Targeting HEAD").anyTimes();
        replay(APPLE);
    }

    // no @BeforeClass needed anymore

    [...]
}

这既解决了我上面简化测试中的问题,也解决了我们实际测试编码中的问题。

我没有找出触发不同异常消息的不同之处,但发现是相同的- new只调用了一次,@BeforeClass被调用了多次,第二次运行失败。修复方法在这两种情况下也都有效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10093105

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档