我使用的enum单例看起来(有点)像这样:
public enum mySingleton{
INSTANCE;
private static String myDrink = null;
public String getMyDrink(boolean isWizard)
{
if (myDrink == null)
{
if (isWizard)
myDrink = "Butterbeer";
else
myDrink = "Whiskey";
}
return myDrink;
}
//Some more functionality
//...
}
现在,为了测试这个单例,我有一些使用它的测试。但是由于所有测试都在同一个线程中一个接一个地运行,所以一旦我运行第一个测试,就会为所有其他测试设置myDrink
。
我不喜欢那样。
我想到使用@After
函数并使用反射来将myDrink
设置为null。
我试过这个:
Field f = mySingleton.class.getField("myDrink");
f.setAccessible(true);
f.set(String.class, null);
但我得到java.lang.NoSuchFieldException
。
怎么做?
答案 0 :(得分:2)
myDrink
字段不应该是静态的。将其设为非静态字段,然后使用
f.set(mySingleton.INSTANCE, null);
另外,请使用getDeclaredField
代替getField
。 getField
查找公共字段。
如果您无法将其更改为非静态,则忽略第一个参数,因此只需使用
f.set(null, null);
答案 1 :(得分:2)
getField()方法只能访问PUBLIC字段。 试试getDeclaredFields()
答案 2 :(得分:1)
对于f.set(...)中的第一个参数,使用null,来自Field.set javadocs,
If the underlying field is static, the obj argument is ignored; it may be null.
正如loodakawa所说,使用getDeclaredField,因为myDrink是私有的。
答案 3 :(得分:1)
由于这仅用于测试目的,您可以添加包本地设置器。一个通常无法访问的。
/* can only be called from tests in the same package */
void resetMyDrink() {
myDrink = null;
}