java - EasyMock - 调用具有不同签名的方法时行为发生变化

标签 java easymock java-11

我目前有一个使用 EasyMock 3.4 运行良好的单元测试,但是当我尝试使用 EasyMock 4.0.2 编译和运行它时,我注意到一个我不太理解的奇怪行为:

我有一个包含以下两种方法的类(请注意签名更改):

public TestAccessSource setAccess(Class<?> clazz, Object access) {
    return setAccess(clazz.getName(), access);
}

public TestAccessSource setAccess(Class<?> clazz, InterfaceA access) {
    return setAccess(clazz, (Object) access);
}

我在单元测试中调用 setAccess 方法,如下所示:

testSources.setAccess(InterfaceB.class, EasyMock.createNiceMock(InterfaceB.class));

在 3.4 中,调用以 Object 作为第二个参数的 setAccess 方法,在 4.0.2 中,调用以 InterfaceA 作为第二个参数被调用,抛出 java.lang.ClassCastException,因为接口(interface)不相关 - 它们唯一的共同点是它们扩展了 Remote 接口(interface)。

如果我只是使用 InterfaceB 的实现而不是模拟它,则会调用正确的 setAccess 方法:

testSources.setAccess(InterfaceB.class, new InterfaceB(){});

这是重现该行为的完整工作示例。第一个 setAccess 有效,但第二个失败。在 EasyMock 3.4 上运行时两者都工作正常:

public class TestEasyMockBehavior {

    public static void main(String[] args) {
        TestAccessSource testSources = new TestAccessSource();
        testSources.setAccess(InterfaceB.class, new InterfaceB(){});
        testSources.setAccess(InterfaceB.class, EasyMock.createNiceMock(InterfaceB.class));
    }

    public static class TestAccessSource {
        public TestAccessSource setAccess(Class<?> clazz, Object access) {
            return setAccess(clazz.getName(), access);
        }

        public TestAccessSource setAccess(Class<?> clazz, InterfaceA access) {
            return setAccess(clazz, (Object) access);
        }

        public TestAccessSource setAccess(String key, Object access) {
            System.out.println(key + " - " + access.getClass().getName());
            return this;
        }
    }

    public interface InterfaceA extends Remote {}

    public interface InterfaceB extends Remote {}
}

我正在寻求一些帮助来理解为什么会发生这种情况以及到底发生了什么变化。我找不到与此行为相关的任何问题。

最佳答案

它与 EasyMock 4 相关,而不是 Java 11。事实上,我更改了 EasyMock 4 的键入。之前是 T mock(Class<T>) 。这真的很烦人,因为一旦你想做 List<String> list = (List) mock(List.class)您会收到警告。

所以我决定输入 T mock(Class<?>) 。问题已解决,类型已推断。

缺点是在某些情况下无法推断,或者在极少数情况下无法正确推断。但在我看来,这些情况是异常(exception)的,因为通常您将模拟分配给一个变量,以便能够记录内容然后重播。

要解决您的问题,您有两种解决方案:

  1. testSources.setAccess(InterfaceB.class, (InterfaceB) mock(InterfaceB.class));
  2. testSources.setAccess(InterfaceB.class, EasyMock.<InterfaceB>mock(InterfaceB.class));

关于java - EasyMock - 调用具有不同签名的方法时行为发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57631271/

相关文章:

java - android - RecyclerView - 不创建项目(跳过它)

java - 如何让回文程序不识别空格并以句点结尾?

java - EasyMock java.lang.AssertionError : Unexpected method call

java - 在 Java 11 中反序列化 XStream XML 时出错 - 无法通过 JDK 序列化创建 java.beans.PropertyChangeSupport : null

java - 是否有一种轻量级的方法来获取上下文句柄以获取资源?

java - 使用以数字开头的字符串来显示那么多字符的子字符串

java - Scala 想告诉我什么,我该如何解决? [需要 : java. util.List[?0] 类型 ?0]

unit-testing - 使用 Spring 注入(inject) EasyMock 模拟导致 ClassCastException

java - 无法使用 JMOD 打包已签名的 Java 安全提供程序

java - Gradle如何添加VM选项以在javafx 11 idea上运行和部署jfoenix?