Java 绕过方法存根中的构造函数调用
我目前正在使用java JSP页面作为测试框架。我在这方面没有太多的经验。然而,有一个问题我找不到解决办法 问题是,我想测试一个不可变的类。您只能使用构造函数初始化属性。访问器(getter)可以检索这些值。但是,其中一个setter方法有一个执行另一个类的构造调用的方法Java 绕过方法存根中的构造函数调用,java,unit-testing,mockito,Java,Unit Testing,Mockito,我目前正在使用java JSP页面作为测试框架。我在这方面没有太多的经验。然而,有一个问题我找不到解决办法 问题是,我想测试一个不可变的类。您只能使用构造函数初始化属性。访问器(getter)可以检索这些值。但是,其中一个setter方法有一个执行另一个类的构造调用的方法 public class MyImmutableClass { private final String foo; private final String bar; private final int
public class MyImmutableClass {
private final String foo;
private final String bar;
private final int jeez;
public MyImmutableClass(String f, String b, Integer j) {
this.foo = setFoo(f);
// same for other fields
}
private String setFoo(String newFoo) {
String retVal = "";
List<String> identifiers = new MyDataBaseHandler().getListOfIdentifiers(); // construct call
if (identifiers.contains(newFoo)) {
// ...
}
else {
// ...
}
return retVal;
}
public boolean isValid() {
// returns the correctness of this instance
}
}
方法this.getIdentifiers()是一个私有方法,用于复制字符串列表。(为了测试起见,该列表中只放了3个元素)。这是为了确保标识符的验证正确地完成任务
然而,这个测试失败了。问题在于getListOfIdentifiers()
在方法体中有一个私有方法调用。这会抛出一个NPE。显然,很难“绕过”在getListOfIdentifiers()
方法中进行的构造调用。callToMyPrivateMethod()
与数据库连接。由于单元测试在本地运行,因此无法建立数据库连接。因此,我想使用Mockito绕过返回值
public List<String> getListOfIdentifiers() {
// ...
callToMyPrivateMethod(); // throws NPE ...
// ...
return list;
}
这一行实际上是一条语句,它在数据库连接上创建一条准备好的语句(它本身不是null…keh)。准备好的声明抛出了一个NPE。将mock(…)
替换为spy(new MyDataBase())
ofc不起作用,因为它是与正在构造的实例不同的实例
我也尝试过@InjectMock
这件事,但这无助于解决我的问题。可能是因为我没有正确地实现注入(doc对此不太清楚)
有没有办法解决这个问题,使Mockito框架拦截对
getListOfIdentifiers()
的调用,然后返回到我创建的列表?或者我是不是开始出现XY
问题?在测试方法中创建新MyDataBaseHandler()
的实例
newmydatabasehandler()
是您的测试类与之通信的依赖项。你正确地认识到了这一点,因为你试图模仿它
但根据您当前的实现,您不能
有两种解决方案
newmydatabasehandler()
,以返回MyDataBaseHandler
类的模拟。但我个人认为使用PowerMock是对糟糕设计的屈服
MyImmutableClass
之外创建MyDataBaseHandler
的实例,并最好通过构造函数将其注入MyImmutableClass
对象中
然后,您就可以轻松地用已经创建的mock替换此依赖项有帮助吗?除非你能重构,否则看起来你必须使用PowerMock。啊,我对DI很熟悉。但是(我刚刚意识到)
setFoo(…)
并不是在我的示例中首先被调用的。向构造函数提供的其他参数将首先进行验证。如果验证程序成功,将调用setFoo(…)
。我实际上是在限制数据库结构。但是,嘿,我刚刚意识到我可以提供一个功能足够多的flyweight db处理程序对象,并将其提供给对象构造函数。我回去工作后会调查的。
public List<String> getListOfIdentifiers() {
// ...
callToMyPrivateMethod(); // throws NPE ...
// ...
return list;
}
java.lang.NullPointerException
at package.MyDataBaseHandler.callToMyPrivateMethod(MyDataBaseHandler.java:67)
at package.MyDataBaseHandler.getListOfIdentifiers(MyDataBaseHandler.java:25)