考虑以下"生产"代码:
public class Foo<T extends Number> {
private Bar delegate;
private Class<T> numberClass;
public Foo(Class<T> numberClass) {
this.numberClass = numberClass;
}
public T doSomething() {
if (numberClass==Integer.class) {
return delegate.getIntValue();
} else if (numberClass==Float.class) {
return delegate.getFloatValue();
} else if (numberClass==Double.class) {
return delegate.getDoubleValue();
} // etc etc etc
return null;
}
}
这是基于我面临的真实情况......我无法控制委托对象的实现。
那么,我如何使用JMockit @Tested
注释对此类进行单元测试?我无法使用@Injectable
来注入Class
值...它抱怨Class
不可模仿。我并没有试图嘲笑它,只是注入它。与字符串或原语或枚举不同,我可以说@Injectable("foobar") String s;
并获得非模拟的可注射对象,这些语义不适用于Class
个对象。
显然,我的解决方法是用Foo
方法手工构建我的@Before
,所以我会这样做。但我无法帮助,但感觉JMockit应该可以实现这种情况。
答案 0 :(得分:1)
简而言之,您不能使用@Tested
因为jmockit不允许您模拟Class
类。你必须写下你的测试:
@Test
public void testDoSomethingWithInteger(@Mocked final Bar bar) {
final int expectedValue = 10;
new NonStrictExpectations() {
{
bar.getIntValue();
result = expectedValue;
}
};
Foo foo = new Foo(Integer.class);
assertEquals(expectedValue, foo.doSomething());
}
我认为限制模拟核心java类的原因是由于模拟这些类可能会对执行java产生不利影响,因为核心类通常会影响代码的大部分。这个SO answer遵循类似的路线或推理。
或者它可能与在类加载器中加载类的方式有关。我确实阅读了a blog post,声称通过使用这些命令行参数启动测试jvm来模拟核心类:-Xbootclasspath/a:jmockit.jar: -javaagent:jmockit.jar
。