如何仅使用EasyMock模拟继承E接口的泛型类?
使用EasyMock模拟泛型类并处理类型判断场景
我明白你被这个泛型类的Mock问题卡了一周有多难受,咱们先把核心问题拆解清楚,一步步解决它——首先有个关键细节你可能没注意到:Java的Class是final类,EasyMock基于动态代理实现,没办法直接Mock final类的对象。所以直接模拟Class<? extends E>这条路走不通,得换个思路,同时满足你用EasyMock创建NiceMock、处理类型判断场景的需求。
第一步:封装Class依赖,绕过final类限制
因为Class是final类无法直接Mock,我们可以创建一个自定义接口来封装需要用到的Class方法(比如isAssignableFrom),这样就能用EasyMock来Mock这个接口了:
// 定义封装Class操作的接口 public interface TypeWrapper { // 对应Class.isAssignableFrom的逻辑 boolean isAssignableFrom(Class<?> targetClass); // 如果你的代码里还用到了Class的其他方法(比如cast、newInstance),也可以在这里添加 }
然后修改你的泛型类,让它依赖这个TypeWrapper而不是直接依赖Class<? extends E>:
public interface E {} public class A implements E {} public class YourGenericClass<T extends E> { private final TypeWrapper typeWrapper; // 构造函数注入TypeWrapper替代原来的Class参数 public YourGenericClass(TypeWrapper typeWrapper) { this.typeWrapper = typeWrapper; } public final Simple limit() { // 把原来的A.class.isAssignableFrom(type)替换为封装后的方法调用 if (typeWrapper.isAssignableFrom(A.class)) { // 这里是你需要触发的业务逻辑,后续我们会Mock这个分支的依赖 return new Simple("A类型匹配成功"); } return new Simple("默认返回"); } } // 假设Simple是你的返回类 public class Simple { private String value; public Simple(String value) { this.value = value; } public String getValue() { return value; } }
第二步:用EasyMock创建TypeWrapper的NiceMock并设置Expect语句
现在我们可以轻松用EasyMock创建TypeWrapper的NiceMock,并且设置期望让类型判断的条件成立:
import org.easymock.EasyMock; import org.junit.Test; import static org.junit.Assert.assertEquals; public class YourGenericClassTest { @Test public void testLimit_WhenTypeMatchesA() { // 1. 创建TypeWrapper的NiceMock TypeWrapper mockTypeWrapper = EasyMock.createNiceMock(TypeWrapper.class); // 2. 设置Expect语句:当调用isAssignableFrom(A.class)时返回true,触发目标分支 EasyMock.expect(mockTypeWrapper.isAssignableFrom(A.class)).andReturn(true); // 激活Mock EasyMock.replay(mockTypeWrapper); // 3. 创建泛型类实例,注入Mock对象 YourGenericClass<E> genericClass = new YourGenericClass<>(mockTypeWrapper); // 4. 调用limit方法并验证结果 Simple result = genericClass.limit(); assertEquals("A类型匹配成功", result.getValue()); // 5. 验证Mock的调用情况(可选) EasyMock.verify(mockTypeWrapper); } }
补充:如果你的代码中需要用到Class的其他方法
比如如果limit()方法里需要用type来做类型转换(type.cast(obj)),只需要在TypeWrapper接口中添加对应的方法,然后在Mock中设置期望:
// 扩展TypeWrapper接口 public interface TypeWrapper { boolean isAssignableFrom(Class<?> targetClass); <U> U cast(Object obj); } // 在测试中添加Expect语句 EasyMock.expect(mockTypeWrapper.cast(EasyMock.anyObject())).andReturn(new A());
这样就能完整模拟你需要的所有Class操作了。
内容的提问来源于stack exchange,提问作者Kinjal Rathod
相关产品推荐
相关产品推荐

