我有在NetBeans插件中使用的这种方法:
public static SourceCodeFile getCurrentlyOpenedFile() {
MainProjectManager mainProjectManager = new MainProjectManager();
Project openedProject = mainProjectManager.getMainProject();
/* Get Java file currently displaying in the IDE if there is an opened project */
if (openedProject != null) {
TopComponent activeTC = TopComponent.getRegistry().getActivated();
DataObject dataLookup = activeTC.getLookup().lookup(DataObject.class);
File file = FileUtil.toFile(dataLookup.getPrimaryFile()); // Currently opened file
// Check if the opened file is a Java file
if (FilenameUtils.getExtension(file.getAbsoluteFile().getAbsolutePath()).equalsIgnoreCase("java")) {
return new SourceCodeFile(file);
} else {
return null;
}
} else {
return null;
}
}
基本上,它使用NetBeans API来检测用户当前在IDE中打开的文件。然后,它加载它并从中创建一个SourceCodeFile
对象。
现在,我想使用JUnit对这种方法进行单元测试。问题是我不知道如何测试。
由于它不接收任何参数作为参数,因此我无法测试给定参数时其行为。我还考虑过尝试操作openedProject
来测试给定对象一些不同值的方法行为,但是就我而言,我无法以这种方式操作JUnit中的变量。我也无法检查方法返回的内容,因为单元测试将始终返回null,因为它不会检测到NetBeans中任何打开的文件。
所以,我的问题是:如何进行这种方法的单元测试?
答案 0 :(得分:3)
好吧,您的方法确实采用了“在行之间”的参数:
MainProjectManager mainProjectManager = new MainProjectManager();
Project openedProject = mainProjectManager.getMainProject();
基本上获取要处理的对象。
所以第一步就是将方法签名更改为:
public static SourceCodeFile getCurrentlyOpenedFile(Project project) {
...
当然,除了该空检查之外,不使用该对象。因此, next 级别将具有类似的方法
SourceCodeFile lookup(DataObject dataLookup) {
换句话说:您真正的问题是您编写了难以测试的代码。 “默认”答案是:您必须更改生产代码,以使其易于测试。
例如,将其撕开,然后将所有不同的方面放入较小的辅助方法中。
您会看到,最后一个方法lookup()
带有一个参数,现在(某种程度上)可以为此考虑测试用例了。可能必须使用Mockito之类的模拟框架才能在测试代码中传递该DataObject类的 mocked 实例。
长话短说:这里没有弯路。您无法(以合理的方式)测试您当前的代码结构。重新构造您的生产代码,然后您所有有关“当我通过X,然后应该发生Y”的想法都可以解决。
免责声明:是的,从理论上讲,您可以通过严重依赖PowerMock(ito)或JMockit等框架来测试上述代码。这些框架允许您new()
的调用。因此,它们将使您完全控制方法中的所有内容。但这基本上会迫使您的测试了解被测方法中正在发生的所有事情。这真是一件坏事。