EasyMock - 调用具有不同签名的方法时行为发生变化
EasyMock - Behavior changed when invoking method with different signatures
我目前有一个单元测试 运行 使用 EasyMock 3.4 没问题,但是当我尝试使用 EasyMock 4.0.2 编译并 运行 它时,我注意到一个我不知道的奇怪行为不太懂:
我有一个 class 有两种方法如下(注意签名更改):
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
作为第二个参数的 setAccess
方法,抛出一个 java.lang.ClassCastException
,因为接口不相关 - 它们唯一的共同点是它们扩展了 Remote
接口。
如果我只是使用 InterfaceB
的实现而不是模拟它,则会调用正确的 setAccess
方法:
testSources.setAccess(InterfaceB.class, new InterfaceB(){});
这是重现该行为的完整工作示例。第一个 setAccess
有效,但第二个失败。在 EasyMock 3.4 上 运行ning 时两者都工作正常:
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<?>)
。问题解决,类型推断。
缺点是在某些情况下无法推断,或者在极少数情况下无法正确推断。但是根据我的说法,这些情况是例外的,因为通常您将模拟分配给一个变量,以便能够记录东西然后重放。
要解决您的问题,您有两个解决方案:
testSources.setAccess(InterfaceB.class, (InterfaceB) mock(InterfaceB.class));
testSources.setAccess(InterfaceB.class, EasyMock.<InterfaceB>mock(InterfaceB.class));
我目前有一个单元测试 运行 使用 EasyMock 3.4 没问题,但是当我尝试使用 EasyMock 4.0.2 编译并 运行 它时,我注意到一个我不知道的奇怪行为不太懂:
我有一个 class 有两种方法如下(注意签名更改):
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
作为第二个参数的 setAccess
方法,抛出一个 java.lang.ClassCastException
,因为接口不相关 - 它们唯一的共同点是它们扩展了 Remote
接口。
如果我只是使用 InterfaceB
的实现而不是模拟它,则会调用正确的 setAccess
方法:
testSources.setAccess(InterfaceB.class, new InterfaceB(){});
这是重现该行为的完整工作示例。第一个 setAccess
有效,但第二个失败。在 EasyMock 3.4 上 运行ning 时两者都工作正常:
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<?>)
。问题解决,类型推断。
缺点是在某些情况下无法推断,或者在极少数情况下无法正确推断。但是根据我的说法,这些情况是例外的,因为通常您将模拟分配给一个变量,以便能够记录东西然后重放。
要解决您的问题,您有两个解决方案:
testSources.setAccess(InterfaceB.class, (InterfaceB) mock(InterfaceB.class));
testSources.setAccess(InterfaceB.class, EasyMock.<InterfaceB>mock(InterfaceB.class));