使用反射重置枚举单例字段



我正在使用一个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

怎么做呢?

myDrink字段不应该是静态的。将其设置为非静态字段,然后使用

f.set(mySingleton.INSTANCE, null);

同样,使用getDeclaredField代替getFieldgetField查找公共字段

如果不能将其更改为非静态,则忽略第一个参数,因此只需使用

f.set(null, null);

getField()方法只能访问PUBLIC字段。试试getDeclaredFields()

对f.set(…)中的第一个参数使用null,来自字段。javadoc,

If the underlying field is static, the obj argument is ignored; it may be null.  

和loodakawa说,使用getDeclaredField,因为myDrink是私有的

因为这只用于测试目的,所以您可以添加一个包本地设置器。一个通常无法访问的对象。

/* can only be called from tests in the same package */
void resetMyDrink() {
    myDrink = null;
}

最新更新