是否可以强制设置内部变量以进行单元测试?

时间:2016-06-08 08:39:57

标签: java unit-testing mocking

我在下面写了一个简单的函数来说明我试图实现的目标。

public class MyTempClass {
    private boolean myVariable = false;

    private void setupMyVariable() {
        // Some callback etc from a web service that will determine the myVariable value
        myVariable = true;
    }

    public void doSomethingIfVaraibleIsTrue() {
        if (myVariable) {
            // Do something.
        }
    }
}

我希望单元测试MyTempClass doSomethingIfVaraibleIsTrue函数在myVariable为真时执行某些操作,而在myVariable为假时不执行某些操作。但是myVariable是一个私有布尔值,并且不容易设置(例如,它是从服务的回调中设置的)。

我也不想为myVariable制作一个setter,因为它对班级来说是非常私人的。有没有办法模拟/梭哈或让myVariable成为真,以便我可以单独测试我的doSomethingIfVaraibleIsTrue

2 个答案:

答案 0 :(得分:3)

根据我的观点,仅出于测试目的,您不得更改任何字段或方法的可见性。这是错误的做法,它打破了封装。

相反,您可以在某些Util类中定义一个泛型方法,然后您可以通过反射更改私有变量的值。您可以定义某种Util类,比如TestUtils,在其中你可以使用以下方法:

class TestUtils {

    public static void setPrivateField(Object targetObject, String fieldName,
          Object valueToSetOnThisField) {

          try {
             Field f = obj.getClass().getDeclaredField(fieldName);
             f.setAccessible(true);
             f.set(obj, valueToSet);
          } catch (Exception e) {
            // Handle the exception accordingly
          }
       }
}

现在您可以在测试类中使用此类,如下所示:

MyTempClass targetObj = new MyTempClass();

// Change private variable "myVariable" to true
TestUtils.setPrivateField(targetObj, "myVariable", Boolean.TRUE);

答案 1 :(得分:1)

使包可见,然后它可以由测试类读取和设置,但不能由其他类读取,即删除私有关键字但不要公开。 IE

public class MyTempClass {
    boolean myVariable = false;

    private void setupMyVariable() {
        // Some callback etc from a web service that will determine the myVariable value
        myVariable = true;
    }

    public void doSomethingIfVaraibleIsTrue() {
        if (myVariable) {
            // Do something.
        }
    }
}