我现在对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)测试用例中访问它?
答案 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);
}