我目前有一个使用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中,调用以setAccess
作为第二个参数的Object
方法,在4.0.2中,调用以setAccess
作为第二个参数的InterfaceA
方法,抛出java.lang.ClassCastException
,因为接口不相关-它们唯一的共同之处在于它们扩展了Remote
接口。
如果我只是使用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 {}
}
我正在寻找帮助,以了解发生的原因以及发生了什么变化。我找不到与此行为有关的任何问题。
答案 0 :(得分:4)
它与EasyMock 4而不是Java 11有关。实际上,我更改了EasyMock 4的类型。在<table>
<tbody>
<tr ng-if="PlacesOfInterest.length > 0" role="row" class="text-center" ng-repeat="row in PlacesOfInterest | filter: search | limitTo: limit as filterPlaces " ng-cloak>
<td style="vertical-align:middle"><span class="" ng-bind="row.PlaceName"></span></td>
{{row.PlaceName}}
<td><img ng-if="row.PlacePhotos.length > 0" src="{{row.PlacePhotos[0].URL}}" alt="No Image" style="height:150px; width:100%" /></td>
<td>
<span ng-init="max = 200" ng-bind="row.PlaceDescription.slice(0,max)"></span>
<a ng-show="row.PlaceDescription.length > 200 && max == 200" ng-click="max = 10000">... <span class="more-less"> more</span></a>
<a class="more-less" ng-show="max > 200" ng-click="max = 200"> less</a>
</td>
<td>
<div class="d-flex">
<a class="btn btn-sm mr-1 btn-modify-places btn-min-width">Edit</a>
<a class="btn btn-sm mr-1 btn-default-places btn-min-width">Specialities</a>
<a class="btn btn-sm btn-delete-places btn-min-width">Delete</a>
</div>
</td>
</tr>
</tbody>
</table>
之前。真令人讨厌,因为一旦您想T mock(Class<T>)
就会收到警告。
因此,我决定键入List<String> list = (List) mock(List.class)
。问题解决了,类型被推断。
缺点是在某些情况下无法推断出,或者更罕见的是无法正确推断出。但是这些情况在我看来是例外的,因为一般来说,您将模拟分配给变量以能够记录内容然后重播。
要解决您的问题,您有两种解决方法:
T mock(Class<?>)
testSources.setAccess(InterfaceB.class, (InterfaceB) mock(InterfaceB.class));