我想使用JMockit创建虚拟对象(see definition here)。
这些对象是非空构造函数参数所必需的,但特定单元测试不需要这些参数。因为构造函数可能会检查参数(例如使用Objects.requireNonNull
),所以虚拟对象只能是null
。
我想使用像
这样的东西new ObjectWithUnusedDependency(dummy());
其中dummy()
创建一个虚拟对象。
使用
public static <T> T dummy() {
return new MockUp<T>() {}.getMockInstance();
}
如果T
是一个界面,这可能有效,但对于getMockInstance
类,则返回null
。
如果在这样的虚拟对象上调用方法时测试失败,那就太好了。
有没有办法使用JMockit来实现这个目标?
答案 0 :(得分:1)
我认为你的模拟框架应该为你处理这个问题。所以在我看来,真正的解决方案是改变模拟框架。
但是,如果你不改变模拟框架,这仍然是可以解决的。使用javassist - http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/
您的代码将如下所示
import javassist.util.proxy.*;
ProxyFactory f=new ProxyFactory();
f.setSuperclass(Dummy.class);
Class<?>dummyClass=f.createClass();
Dummy dummy=(Dummy)dummyClass.newInstance();
new ObjectWithUnusedDependency(dummy);
如果你这么做,那么创建辅助方法就很聪明了
public static <T> T dummy(Class<T>clazz)
干这四行代码,这样你就得到:
new ObjectWithUnusedDependency(dummy(Dummy.class))
。
它就像java.lang.reflect.Proxy
,除了你也可以代理类。
我认为你仍然会遇到最终类和系统类(java.lang.System,java.lang.Math等)的问题,但是如果你的类需要对java.lang.Math实例的非null引用那么它可能不会在生产中起作用 - 不需要进行单元测试。
答案 1 :(得分:1)
使用JMockit非常容易。只需声明所需类型的模拟字段或模拟参数,并将其传递给测试中的代码。例如:
@Test
public void myTest(@Injectable SomeClass dummy)
{
new ObjectWithUnusedDependency(dummy).doSomething();
}
适用于任何引用类型,包括final
类,abstract
类,接口,枚举等。
此外,如果您想要在虚拟对象上调用任何方法时测试失败,那么&#34;完全验证&#34;需要添加:
@Test
public void myTest(@Injectable SomeClass dummy)
{
new ObjectWithUnusedDependency(dummy).doSomething();
new FullVerifications(dummy) {};
}