使用JMockit为类创建虚拟对象

时间:2014-08-03 11:34:03

标签: java unit-testing jmockit

我想使用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来实现这个目标?

2 个答案:

答案 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) {};
}