mock通过反射从泛型类型的构造函数参数创建mock



我试图为单元测试创建一个基本抽象类。在c#中很容易做到这一点,但在java中却做不到。我的想法是,我将有一个TestFor类,这是用来作为基础的单元测试。T表示待测类型。在这个类中,我想创建类型为T的对象及其最长构造函数的所有参数。这意味着我必须反映类,获得最长的构造函数,提取参数,创建该参数的mock,然后创建t类型的对象。我有以下代码,但不能工作。谁能试试

public abstract class TestFor<T> {
protected Class<T> _class = null;
public HashMap<Class, Class<?>> _mocks = new HashMap<Class, Class<?>>();
protected T Target = null;
protected TestFor(Class<T> cls) {
    _class = cls;
    Constructor<T>[] allConstructors = (Constructor<T>[]) _class.getDeclaredConstructors();
    Constructor<T> ctorWithLongestParameter = null;
    int max = 0;
    for (Constructor ctor : allConstructors) {
        if (ctor.getParameterTypes().length > max) {
            ctorWithLongestParameter = ctor;
            max = ctor.getParameterTypes().length;
        }
    }
    final List<Object> objects = new ArrayList<Object>();
    int i = 0;
    for (Class<?> p : ctorWithLongestParameter.getParameterTypes()) {
        Class<?> mock = Mockito.mock(p.getClass()); //This does not work
        _mocks.put(p.getClass(), mock);
        objects.add(mock);
    }
    try {
        Target = (T) ctorWithLongestParameter.newInstance(objects);
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}
public <E> E the(Class clss) {
    return (E) _mocks.get(clss);
}

}

你的代码中有几个错误——逻辑、类型、泛型……试试这个:

public abstract class TestFor<T> {
    protected Class<T> _class = null;
    public Map<Class, Object> _mocks = new HashMap<>();
    protected T Target = null;
    protected TestFor(Class<T> cls) {
        _class = cls;
        List<Constructor> allConstructors = Arrays.asList(_class.getDeclaredConstructors());
        Constructor ctorWithLongestParameter = Collections.max(allConstructors,
            (o1, o2) -> Integer.compare(o1.getParameterCount(), o2.getParameterCount()));
        List<Object> objects = new ArrayList<>();
        int i = 0;
        for (Class<?> type : ctorWithLongestParameter.getParameterTypes()) {
            Object mock = _mocks.get(type);
            if (mock == null) {
                mock = Mockito.mock(type);
                _mocks.put(type, mock);
            }
            objects.add(mock);
        }
        try {
            Target = _class.cast(ctorWithLongestParameter.newInstance(objects.toArray(new Object[objects.size()])));
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }
    public <E> E the(Class<E> cls) {
        return cls.cast(_mocks.get(cls));
    }
    public static void main(String[] args) {
        TestFor<A> test = new TestFor<A>(A.class) {};
        System.out.println(test.Target);
        System.out.println(test.the(Object.class));
        System.out.println(test.the(Number.class));
    }
    public static class A {
        public A() {
            System.out.println("Empty constructor");
        }
        public A(Object o) {
            System.out.println("Constructor [o=" + o + ']');
        }
        public A(Object o, Number n) {
            System.out.println("Constructor [o=" + o + ", n=" + n + ']');
        }
    }
}

此代码适用于Java 8,但是经过一些小修改后,它将适用于旧版本。

最新更新