在JUnit测试类中使用类中的常量

时间:2018-05-23 14:16:25

标签: java junit junit5

我现在对Java很平庸,对JUnit不熟悉,但我在其他地方找不到这个问题的答案。

我想在Junit测试用例本身内使用我正在测试的类中定义的常量变量,但由于它是静态final,所以它不可用。

我正在测试的课程如下:

public class MyClass {
    private static final int HSIZE = 7;
    private static final int NUM_LOCS = 3;
    .
    .
    .

    void generateRandomLocations() {
        Random rand = new Random();
        String[] hPos = new String[NUM_LOCS]; 

        for (int i=0; i<NUM_LOCS; i++) {
            hPos[i] = Integer.toString(rand.nextInt(HSIZE)); 
        } 
        setLocations(hPos);
    }
}

很简单,似乎工作正常,但我想在JUnit中添加一个测试用例 - 如下所示:

@Test
void testGenerateRandomLocations() {
    MyClass mc = new MyClass();

    mc.generateRandomLocations();

    String[] check = mc.getLocations();
    assertEquals(sadc.NUM_LOCS, check.length);

    }

(定义了getter,为了简洁,我还没有把它包括在内)

然而(当然)sadc.NUM_LOCS不可用,因为它只在MyClass中可见。

如何从JUnit(5)测试用例中访问它?

3 个答案:

答案 0 :(得分:1)

我使用了@VisibleForTesting注释,它通常解释为什么私有变量和方法被保护。它们不是完全可见的,但可以出于测试目的进行访问。我将其与private static final变量一起使用。

我看过/使用过的示例使用了一个名为VisibleForTesting.java的文件,其中包含:

package your.pkg.here;

import java.lang.annotation.Retention;

import static java.lang.annotation.RetentionPolicy.SOURCE;
/**
 * Indicates that the class, method or field has greater
 * visibility than otherwise needed to enhance testability.
 */
@Retention(SOURCE)
public @interface VisibleForTesting {
}

然后在您要测试的类中,将方法或变量设置为protected,并使用@VisibleForTesting批注:

public class MyClass {
    private static final int HSIZE = 7;

    @VisibleForTesting
    protected static final int NUM_LOCS = 3;

    void generateRandomLocations() {
        Random rand = new Random();
        String[] hPos = new String[NUM_LOCS]; 

        for (int i=0; i<NUM_LOCS; i++) {
            hPos[i] = Integer.toString(rand.nextInt(HSIZE)); 
        } 
        setLocations(hPos);
    }
}

这可以使测试看到它,但是该变量不公开,并且有一个解释为什么它不是私有的。 @VisibleForTesting也可以在Google的Guava库中找到,因此您可以包括它而不是添加VisibleForTesting.java,但我还没有使用它。

答案 1 :(得分:0)

您是否尝试过使用Powermockito? Whitebox有getInternalState。

看看是否有帮助

https://github.com/powermock/powermock/wiki/Bypass-Encapsulation

答案 2 :(得分:-1)

简单回答

将变量NUM_LOCS公开。然而,这是一个糟糕的设计。

更好的回答

而不是静态变量,通过构造函数传递NUM_LOCS

public class MyClass {

    private final int numLocs;

    public MyClass(int numLocs) {
        this.numLocs = numLocs;
    }

    //default ctor with default numLocs value
    public MyClass() {
        this.numLocs = 3;
    }

    //methods

}

现在,您的测试看起来像这样:

@Test
void testGenerateRandomLocations() {
    int expectedNumLocs = 7;
    MyClass mc = new MyClass(7);
    mc.generateRandomLocations();
    String[] check = mc.getLocations();
    assertEquals(expectedNumLocs, check.length);
}

你可以做一个测试来检查默认值是3:

@Test
void testGenerateRandomLocations() {
    int expectedNumLocs = 3;
    MyClass mc = new MyClass(); //no args
    mc.generateRandomLocations();
    String[] check = mc.getLocations();
    assertEquals(expectedNumLocs, check.length);
}