我目前有一个使用 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)的,因为通常您将模拟分配给一个变量,以便能够记录内容然后重播。
要解决您的问题,您有两种解决方案:
-
testSources.setAccess(InterfaceB.class, (InterfaceB) mock(InterfaceB.class));
-
testSources.setAccess(InterfaceB.class, EasyMock.<InterfaceB>mock(InterfaceB.class));
关于java - EasyMock - 调用具有不同签名的方法时行为发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57631271/