当前位置: 首页 > 知识库问答 >
问题:

当单元测试子类时,如何在抽象类中注入变量?

管翼
2023-03-14

我有一个抽象类BaseTemboard和多个扩展它的类。在其中一个具体类(SmsTemboard扩展BaseTemboard)中,我们有一个私有变量Gson。我们在抽象类中也有相同的私有变量(Gson)。

当单元测试具体类时,抽象类中的方法从具体类中被调用。在我的Unit测试中,我使用Whitebox.setInternalState(smsTemplateObj, gsonObj);将Gson对象注入到SmsTem板BaseTem板的私有成员中,但是Gson只被注入到子类中...在抽象类中,它的NULL,表示未注入。下面是实现。

有人能告诉如何在抽象类中注入Gson对象吗?

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);
    }
}

共有2个答案

范朗
2023-03-14

您需要第二个抽象层:

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);
    }
}
乐刚毅
2023-03-14

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

对于这种情况,有两种解决方案:

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

片段:

Field field = smsTemplateObj.getClass().getSuperclass().getDeclaredField("gson");
field.setAccesible(true);
field.set(smsTemplateObj, gsonObj);
 类似资料:
  • 我通过学校为一项任务提供的简报创建了一个飞机座位预订系统。我遇到了一个我无法解决的主要问题。 摘要说明抽象类必须有一个抽象方法和大约4个公共方法。在抽象类的两个子类中,我们都必须初始化对象数组(所有普通的座位)。然而,一旦它们被初始化,我不知道如何将它们发送回抽象类(该类有一个检查未预订的飞机座位的方法,这就是我需要初始化的座位对象的地方) ArrayIndexOutOfBounds在一个应该在边

  • 我有一个问题是将EJB注入到抽象类中,抽象类是我JSF CDI bean的父类。在我的项目中,我使用MyFaces CODI 1.0.5(ViewScope),Omniface 1.3,PrimeFaces 3.4.2和GlassFish3.1.2。 应用程序是一个EAR,抽象类位于EJB模块中,JSF CDI bean位于WAR模块中: 我的抽象类: 我的CDIBean: 当我部署应用程序并访问

  • 问题内容: 我是第一次使用JUnit进行Java测试。我必须使用Java,并且想使用单元测试。 我的问题是:我有一个带有一些抽象方法的抽象类。但是有些方法不是抽象的。如何使用JUnit测试此类?示例代码(非常简单): 我要测试并运行。 在“JUnit常见问题解答”部分中,我找到了此链接,但我不理解作者想在此示例中说些什么。这行代码是什么意思? 问题答案: 如果您没有该类的具体实现,并且方法不是测试

  • 知道为什么@Context注入在单元测试时不起作用吗?

  • 请考虑以下代码: 此外,出现此错误的原因可能是:1。您使用final/private/equals()/hashCode()方法中的任一个作为存根。这些方法不能被截取/验证。不支持在非公共父类上声明的模拟方法。2.内部when()不是对mock而是对其他对象调用method。 我是通过Guice进行依赖注入的新手,不知道为什么我不能以这种方式模拟实现对象?

  • 我从Wicket开始,正在做TDD(当然是使用WicketTester) 我在尝试使用标记继承创建公共布局时遇到了一个问题 我查看了包括这一个在内的在线示例。然而,这些示例没有提到如何测试父类。 问题是父类是抽象的。这意味着,无法实例化页面,它会抛出一个异常(这是理所当然的) 我曾想过使用mock或fake类将该类作为常规POJO进行测试,但之后我将无法测试抽象父类中的wicket组件 我考虑的另