java - JUnit - 如何对读取目录中的文件并使用外部库的方法进行单元测试
问题描述
我在 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 中打开的任何文件。
所以,我的问题是:我该如何处理这种方法的单元测试?
解决方案
好吧,您的方法确实采用“字里行间”的参数:
MainProjectManager mainProjectManager = new MainProjectManager();
Project openedProject = mainProjectManager.getMainProject();
基本上获取要处理的对象。
因此,第一步是将该方法签名更改为:
public static SourceCodeFile getCurrentlyOpenedFile(Project project) {
...
当然,除了那个空检查之外,没有使用那个对象。所以下一个级别将是有一个独特的方法,比如
SourceCodeFile lookup(DataObject dataLookup) {
换句话说:您真正的问题是您编写了难以测试的代码。“默认”答案是:您必须更改生产代码,以便更容易测试。
例如,将其拆分,并将所有不同的方面放入较小的辅助方法中。
你看,最后一个方法lookup()
,那个方法接受一个参数,现在(不知何故)有可能为此考虑测试用例。您可能必须使用 Mockito 等模拟框架在测试代码中传递该DataObject类的模拟实例。
长话短说:这里没有弯路。您无法(以合理的方式)测试您的代码,因为它目前是结构化的。重新构建你的生产代码,然后你所有关于“当我通过 X,然后 Y 应该发生”的想法都可以解决。
免责声明:是的,理论上,您可以通过严重依赖 PowerMock(ito) 或 JMockit 等框架来测试上述代码。这些框架允许您控制(模拟)对静态方法的调用,或对new()
. 所以他们会让你完全控制你方法中的一切。但这基本上会迫使您的测试了解被测方法中发生的一切。这是一件非常糟糕的事情。
推荐阅读
- c++ - 使用 stbi_write_png 从 OpenGL 帧缓冲区保存的 PNG 向右移动
- json - jq遇到某个子值时找出父键
- python-3.x - 多线程请求 Python3
- java - 找到矩阵的重心
- mysql - 如何使用 MinGW-W64 编译 MySQL 连接器 C++?
- html - 字体以不同的大小和风格在四处跳动
- arrays - 潜在面试问题:构建类似于 Excel 列的伪代码字符串增量器
- c# - 为什么我得到 System.Data.Entity.Validation.DbEntityValidationException: by Post 函数
- php - 不在文档根目录中时不提供 PHP
- excel - 如何创建循环以将数据从一个工作表复制并粘贴到另一个工作表