如何在对子 class 进行单元测试时在抽象 class 中注入变量?

How to inject the variable in the abstract class while unit testing the subclass?

我有一个摘要 class BaseTemplate 和多个 class 扩展它。在其中一个具体的 class(SmsTemplate extends BaseTemplate) 中,我们有一个私有变量 Gson。我们在抽象 class 中也有相同的私有变量(Gson)。

在对具体 class 进行单元测试时,从具体 class 调用抽象 class 中的方法。在我的单元测试中,我使用 Whitebox.setInternalState(smsTemplateObj, gsonObj); 将 Gson 对象注入到 SmsTemplateBaseTemplate 的私有成员中,但 Gson 仅在子 class 中注入。 abstract class,其NULL,表示未注入。下面是实现。

谁能告诉我如何在摘要中注入 Gson 对象 class?

abstract class BaseTemplate{

    private Gson gson;//Here its not getting injected

    protected String getContent(Content content){
        return gson.toJson(content); // ERROR - gson here throws NPE as its not injected
    }
}

class SmsTemplate extends BaseTemplate{

    private Gson gson;//Here its getting injected

    public String processTemplate(Content content){
        String strContent = getContent(content);
        ...
        ...
        gson.fromJson(strContent, Template.class);
    }
}

您需要第二个抽象层:

abstract class BaseTemplate{

    // private Gson gson;// no Gson here

    protected String getContent(Content content){
        // do what you want without Gson
    }
}

abstract class BaseTemplateWithGson extends BaseTemplate{

    protected Gson gson;

    @Override
    protected String getContent(Content content){
        return gson.toJson(content);
    }
}

class SmsTemplate extends BaseTemplateWithGson {

    public String processTemplate(Content content){
        String strContent = getContent(content);
        ...
        ...
        gson.fromJson(strContent, Template.class);
    }
}

Whitebox.setInternalState() 方法只会设置它遇到的第一个字段的值,它会通过您传递的对象的层次结构上升。因此,一旦它在您的子类中找到 gson 字段,它就不会进一步查找,也不会更改超类字段。

这种情况有两种解决方案:

  • 更改变量名称。如果变量有不同的名称,您可以简单地调用 Whitebox.setInternalState() 两次,每个变量一个。
  • 使用反射手动设置字段。您也可以在没有 Mockito 帮助的情况下使用类似以下代码段的内容设置字段。

片段:

Field field = smsTemplateObj.getClass().getSuperclass().getDeclaredField("gson");
field.setAccesible(true);
field.set(smsTemplateObj, gsonObj);