处理私有方法(白盒测试),具有许多条件的方法

时间:2015-11-03 14:44:08

标签: java spring unit-testing junit mockito

我有两个问题:

1)在JUnit中,您不应该测试或模拟私有方法。但是当我们在公共方法中调用它们时,我该如何处理呢?我们假设我有以下设置:

public void method(String value){
    if(value.contains("something")){
        doSomethingToString(value);
    }
    else{
        //do something else
    }
}

private void doSomethingToString(String value){
    Object obj = service.getObject();   //service is mocked in my test-class
    //do something with the obj and value
}

我正在进行白盒测试,所以我知道方法和发生了什么。现在我想测试公共方法method(String value)。当我现在只考虑那里发生的事情时,我会遇到麻烦,因为我需要影响我的私有方法返回的service.getObject()。是否可以,当我继续,像我一样,意味着使用doReturn(objectICreatedInMyTestClass).when(service.getObject())或者我需要找到另一种方式?

2)具有多个条件的方法。例如:

public void method(String value){
    if(value.contains("something")){
        Object obj = service.getObj(value);
    }
    else{
        //do something else
    }

    if(obj.getAddress == null){
        //do something
    }
    else{
        //do something else
        }

    if (obj.getName == "Name") {
        // do something
    } 
    else 
    {
        // do something else
    }
}

我需要多少次测试此方法?只有两次,一旦所有条件都恢复正常,第二次,它们都返回假?或者是否建议测试每种可能的情况?这将意味着测试条件1 =真,条件2 =假,条件3 =假,然后条件1 =真,条件2 =真,条件3 =假等等(= 8个可能性)。

1 个答案:

答案 0 :(得分:1)

1)我应该在调用它们的公共方法之外自己测试私有方法吗?

通常我总是遵循这样的假设:如果你的代码访问该方法的唯一方法是通过另一个方法,那么你应该如何测试它。我在测试系统方面的经验让我相信这通常也是在'现实世界'中完成的方式。

如果我们举个例子,我们可以假设我们的第一步是编写测试来彻底测试我们的主要方法。作为其中的一部分,我们应该测试包括正确行使我们可能期望面对的所有条件的情景。这将包括您的私有方法将面临的至少一部分方案。

您的私有方法可能被多个(可能是完全不同的)方法使用,因此其可能的输入和输出空间可能大于使用它的任何单个公共方法。但是,如果您彻底测试使用它们的公共方法,那么您应该处于测试私有方法将遇到的所有可能方案的情况。

因此,您不需要专门为私有方法编写测试。可能还有其他情况下,尝试测试私有方法或私有类是不可避免的。通常我认为这是因为代码只是以一种使其变得困难/不可能的方式编写而且可以被重写以使其对测试更友好(因此在以后更新/重构时更友好)。

2)是否应测试所有这些组合?

这取决于示例中发生的情况。有两种不同的方案需要考虑

a)这些分支都没有任何关系。也就是说,在第一组分支中发生的事情将无法影响第二分支中发生的事情的逻辑。

b)在第一组分支中运行任何逻辑的一些可能的含义将导致一个或多个第二分支中的代码逻辑产生不同的结果。

这将取决于您的阅读并理解代码中发生的事情,因此您的示例不足以指向一种或另一种方式。