如果其中一个构造函数参数是List类型,是否可以使用null参数测试私有构造函数?

时间:2016-06-02 15:46:31

标签: java unit-testing junit4 jmockit

我正在使用jMockit对一些新对象进行单元测试。在我的特定情况下,我试图测试私有构造函数对null参数的反应。考虑这个例子:

public abstract class Foo {

    private final String nickname;

    public Foo(final String nickname) {
        // Check condition
        Preconditions.checkNotNull(nickname);
        // Do some stuff
        int i=0; while (i<10) {i++; System.out.println("I can count to "+i);} 
        // Store value
        this.nickname = nickname;
    }

    public boolean isItMyName(String alias) {
        return (nickname.equalsIgnoreCase(alias));
    }

}

public class Bar extends Foo {

    private final String professionalNickname;
    private final List<String> jailhouseNicknames = new ArrayList<String>();

    private Bar(final String casualNickname, 
            final String professionalNickname,
            final List<String> jailhouseNicknames) {
        super(casualNickname);
        Preconditions.checkNotNull(professionalNickname);
        Preconditions.checkNotNull(jailhouseNicknames);
        this.professionalNickname = professionalNickname;
        this.jailhouseNicknames.addAll(jailhouseNicknames);
    }

    @Override
    public boolean isItMyName(String alias) {
        if (super.isItMyName(alias)) return true;
        if (professionalNickname.equalsIgnoreCase(alias)) return true;
        for (String nick : jailhouseNicknames)
            if (nick.equalsIgnoreCase(alias)) return true;
        return false;
    }

}

如果我想用jMockit测试Bar构造函数,我可以使用Deencapsulation.newInstance(Class classToInstantiate,Object ... nonNullArgs)。但是,在我的情况下,我希望其中一个参数(特别是其中一个字符串)是一个空引用。在这种情况下,我必须使用方法Deencapsulation.newInstance(Class classToInstantiate,Class [] parameterTypes,Object ... initArgs)。这需要我通过Class&lt;列表与LT;字符串&gt; &gt;,但根据this past answer,这是不好的做法,只有通过施法才能实现。

即使我确实谨慎对待风并试图采取行动

Class<List<String>> listClass = ((Class<List<String>>)new ArrayList<String>().getClass());
Deencapsulation.newInstance(
            Bar.class, 
            new Class<?>[] {String.class, String.class, listClass},
            someString, 
            null, 
            someListOfStrings);

我收到错误

  

引起:java.lang.IllegalArgumentException:找不到指定的构造函数:DiscreteSlot(java.lang.String,java.lang.String,java.util.ArrayList)

有没有办法做我正在尝试的事情?

2 个答案:

答案 0 :(得分:1)

您尝试调用的构造函数将List作为第三个参数,因此您应该将List.class作为数组中的第三个类传递,以便反射调用它。

但是,您传递的是此表达式的结果:

((Class<List<String>>)new ArrayList<String>().getClass());

等于

ArrayList.class

由于没有构造函数接受ArrayList,因此它表示没有找到构造函数。

改为通过List.class

答案 1 :(得分:1)

构造函数参数类型为var table = $('#example').DataTable({ "ajax": 'https://api.myjson.com/bins/qgcu', "order": [], "dom": 'Bfrtip', "buttons": { "dom": { "button": { "tag": "button", "className": "waves-effect waves-light btn mrm" } }, "buttons": [ 'copyHtml5', 'excelHtml5', 'csvHtml5', 'pdfHtml5' ] } }); ,而不是List。就这样做:

ArrayList

表达式Deencapsulation.newInstance( Bar.class, new Class<?>[] {String.class, String.class, List.class}, // use List class literal someString, null, someListOfStrings); 返回new ArrayList<String>().getClass(),不等于ArrayList.class