如何在对子 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 对象注入到 SmsTemplate
和 BaseTemplate
的私有成员中,但 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);
我有一个摘要 class BaseTemplate
和多个 class 扩展它。在其中一个具体的 class(SmsTemplate extends BaseTemplate
) 中,我们有一个私有变量 Gson
。我们在抽象 class 中也有相同的私有变量(Gson
)。
在对具体 class 进行单元测试时,从具体 class 调用抽象 class 中的方法。在我的单元测试中,我使用 Whitebox.setInternalState(smsTemplateObj, gsonObj);
将 Gson 对象注入到 SmsTemplate
和 BaseTemplate
的私有成员中,但 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);