-6ren">
gpt4 book ai didi

Java Easymock 提示 "java.lang.IllegalStateException: void method cannot return a value"或 "no last call on a mock available"

转载 作者:行者123 更新时间:2023-11-29 09:14:54 30 4
gpt4 key购买 nike

我们使用 EasyMock 在 Eclipse 中对我们的 Java 应用程序进行 JUnit 测试。使用类似于下面的代码,我们发现了一个奇怪的行为:当运行完整的测试套件(Eclipse 项目 -> 运行方式 -> JUnit)时,一个测试用例重复失败。然而,当它独立运行时它工作正常。

接口(interface):

package de.zefiro.java.easymockexception;

public interface Fruit {
public String fall();
}

测试类:

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"));
}
}

测试套件:

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 项目上运行所有测试——即调用 Newton 和直接调用 Newton 的 ScienceTests——在上面的小例子中产生了这个异常:

java.lang.IllegalStateException: no last call on a mock available
at org.easymock.Easymock.getControlForLastCall(EasyMock.java:175)

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

在我们的真实测试代码中(更大的类,但主要参与者与精简示例相同)这个异常:

java.lang.IllegalStateException: void method cannot return a value
at org.easymock.internal.MocksControl.andReturn(MocksControl.java:101)

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

最佳答案

在初始化 APPLE 的行和 SetUpClass() 内部放置断点 我注意到 APPLE 被调用了一次,而 SetUpClass 被调用了两次。这是因为对 Newton 的第一个引用创建了类并运行了静态初始化程序,但是 JUnit 会为每次运行的测试调用 @BeforeClass。在这种情况下,测试运行两次:一次作为正常调用,一次作为测试套件的一部分。

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

public class Newton {

[...]

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

// no @BeforeClass needed anymore

[...]
}

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

我没有找出触发不同异常消息的区别是什么,但发现是相同的 - new 仅被调用一次,@BeforeClass 被调用多次并在第二次运行时失败。该修复程序也适用于两者。

关于Java Easymock 提示 "java.lang.IllegalStateException: void method cannot return a value"或 "no last call on a mock available",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10093105/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com