我正在尝试使用Spock模拟下面的java方法。
public List<DiffEntry> listDifferences(String oldCommit, String newCommit, Git git)
throws GitAPIException, RevisionSyntaxException, AmbiguousObjectException,
IncorrectObjectTypeException, IOException {
logger.info(
"Inside DiffCommits#listDifferences to calculating difference commits refs {} and {} ",
oldCommit, newCommit);
ObjectId oldTree = git.getRepository().resolve(oldCommit);
ObjectId newTree = git.getRepository().resolve(newCommit);
if (oldTree == null || newTree == null) {
logger.warn(
"Could not resolve either old {} or new commits {}, difference cant not be calculated",
oldCommit, newCommit);
throw new RefNotFoundException("Unable to resolve tag reference. Invalid tag provided");
}
ObjectReader reader = git.getRepository().newObjectReader();
CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
oldTreeIter.reset(reader, oldTree);
CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
newTreeIter.reset(reader, newTree);
DiffFormatter df = new DiffFormatter(new ByteArrayOutputStream());
df.setRepository(git.getRepository());
List<DiffEntry> entries;
entries = df.scan(newTreeIter, oldTreeIter);
df.close();
if (logger.isDebugEnabled()) {
for (int i = 0; i < entries.size(); i++) {
logger.debug("Entry: " + entries.get(i));
}
}
return entries;
}
一切正常,但以下代码的模拟失败
DiffFormatter df = new DiffFormatter(new ByteArrayOutputStream());
在
处出错df.setRepository(git.getRepository());
我得到的错误是
> org.eclipse.jgit.lib.StoredConfig$$EnhancerByCGLIB$$9a2f8398 cannot be
> cast to org.eclipse.jgit.diff.DiffConfig java.lang.ClassCastException:
> org.eclipse.jgit.lib.StoredConfig$$EnhancerByCGLIB$$9a2f8398 cannot be
> cast to org.eclipse.jgit.diff.DiffConfig at
> org.eclipse.jgit.diff.DiffFormatter.setReader(DiffFormatter.java:201)
> at
> org.eclipse.jgit.diff.DiffFormatter.setRepository(DiffFormatter.java:180)
> at
> com.sf.bt.mdm.subscription.scmdiff.DiffCommits.listDifferences(DiffCommits.java:65)
> at com.sf.bt.mdm.subscription.service.DiffCommitSpec.test list
> differences(DiffCommitSpec.groovy:59)
任何帮助将不胜感激
答案 0 :(得分:0)
DiffFormatter df = new DiffFormatter(new ByteArrayOutputStream());
从单元测试的角度来看,此代码是有问题的。它不是依赖项,因此无法将其注入类中。因此,基本上,您正在尝试模拟构造函数(new
)对象。
从技术上讲,您可以尝试的唯一方法是使用Global Mocks并创建包裹实际对象的间谍:阅读documentation。这些不是普通的Spock的“假人”和“存根”。
但是我相信还有其他方法。在我发送给您所有链接之后,出于某种原因,请以“在使用前先三思……”开头;)
您自己决定将创建对象的方法放入方法中,这没关系。但是,这意味着您不会将此DiffFormatter
视为真正的依赖项。因此,即使在单元测试中,您也应该让它运行,专注于自己模拟其输入参数? ByteArrayOutputStream
也是如此。总体而言,这与应该以单元测试不应真正关心方法的内部实现的方式编写代码的概念很好地配合使用。总是比黑盒测试更喜欢黑盒测试。
或者,如果您认为其为依赖项,那么也许应该将其设为数据字段。然后,您可以使用常规模拟将其注入测试中。如果应根据方法调用创建此类,则可以注入Supplier<DiffFormatter> and in method
只是调用它的get方法,它将充当工厂。