如何将@Injectable Class对象应用于@Tested类的构造函数?

时间:2016-05-17 17:44:02

标签: java jmockit

考虑以下"生产"代码:

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应该可以实现这种情况。

1 个答案:

答案 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