为传递参数的私有构造函数编写JUnit测试

时间:2015-08-26 14:46:31

标签: java

我需要编写一个单元测试来测试getRequired()方法,方法是将测试数据传递给私有构造函数private Example(String a,String b)。请帮帮我。

public class Example {

private String str1 = null;
private String str2 = null;

public static void main(String[] args) {    
    Example e = new Example(args[0], args[1]);
    String req = e.getRequired();
    System.out.println(req);
}

private Example(String a, String b)
{
    str1 = new String(a);
    str2 = new String(b);
}

private String getRequired()
{
   //code using str1 and str2 here
   return "success";
}

}

2 个答案:

答案 0 :(得分:1)

从黑盒测试的角度来看

此代码无法测试。你甚至无法实例化它,所以没有现实的方法可以解决这个问题。在测试无法像这样使用的东西时没有任何意义。

如果你想 make 它是可测试的,那么你必须公开一个静态方法来创建它的实例。如果那是一个单身人士或工厂,这取决于你 - 仅仅从你向我们展示的内容中看不出来,但至少这可以让你测试一下没有真的担心私有构造函数。

您还必须设置访问者才能访问这些字段,但要将它们打包为私有字段。

此外,在这种情况下,new String(String)之类的调用是不需要的,并且可能只会让您感到困惑。您已经传递了String,因此您无需创建

最后,从测试的角度来看,getRequired()很难测试;除非它改变实例的状态(再次,你需要用来验证任何东西),否则没有必要对它进行测试。它只会返回"success"

public class Example {

    private String str1 = null;
    private String str2 = null;

    public static void main(String[] args) {
        Example e = new Example(args[0], args[1]);
        String req = e.getRequired();
        System.out.println(req);
    }

    private Example(String a, String b) {
        str1 = new String(a);
        str2 = new String(b);
    }

    String getStr1() {
        return str1;
    }

    String getStr2() {
        return str2;
    }

    private String getRequired() {
        //code using str1 and str2 here
        return "success";
    }

    public static Example getNewInstance(String a, String b) {
        return new Example(a, b);
    }
}

从白盒测试的角度来看

您只能使用反射来获取私有构造函数和字段以验证它们是否已设置。

@Test
public void testExample() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
    Constructor<Example> exampleConstructor = Example.class.getDeclaredConstructor(String.class, String.class);
    exampleConstructor.setAccessible(true);
    Example example = exampleConstructor.newInstance("foo", "bar");

    // verify
    Field str1 = example.getClass().getDeclaredField("str1");
    Field str2 = example.getClass().getDeclaredField("str2");
    str1.setAccessible(true);
    str2.setAccessible(true);

    assertThat("foo", equalTo(str1.get(example)));
    assertThat("bar", equalTo(str2.get(example)));
}

答案 1 :(得分:0)

看起来还有其他两个选择。

通常,私有构造函数意味着该类不能被子类化,并且通过设计导出的API的用户无法直接调用构造函数。在这种情况下,可能存在将要实现的公共静态工厂方法。这允许实例控制,这在下面没有实现。

    public static Example newInstance(String a, String b){
      return new Example(a, b);
    }

另一个选项,如果你必须直接测试构造函数,就是将访问修饰符提升为默认的&#34;包私有&#34;,修饰符。

    Example(String a, String b){...}

您可以在同一个包中添加单元测试并以此方式进行测试。将访问修饰符从私有升级到默认值以便于测试不应该是一个问题。