>我正在开发一个Java应用程序,该应用程序将读取文件,然后将其读入内存后将进行进一步处理。
文件读取的要求是代码应从">当前工作目录"读取。 我编写了一个方法如下:
public List<String> processFile(String fileName){
String localPath = FileSystems.getDefault().getPath(".").toAbsolutePath() + fileName;
}
此方法将文件转换为它返回的 ArrayList。 然后使用此数组列表需要完成进一步的处理。
public boolean workOnFile(){
List<String> records = processFile("abc.txt");
// additional logic
}
我对如何对文件读取部分进行 Junit 感到困惑/困惑,因为要求是文件读取需要从"工作目录"进行,因此无论用户在哪里运行程序,输入文件都将从工作目录中读取。
但是,在Junit的情况下,我的测试文件将位于"\src\main\resources"中 结果,测试文件不会被"processFile"方法读取,因为它在"当前工作目录中"查找文件
一个想法是我不需要 Junit 读取文件,而是整个应用程序在读取文件后执行一些操作 - 所以我是否有一些"测试"规定,在执行 Junit 时,我在 junit 中读取文件,然后在我的类中具有被测试的设置来注入我的 testArrayList?
@Test
public void doSomeValidation() {
String testFile = "XYZ.txt";
ClassUnderTest fixture = new ClassUnderTest();
List<String> testList = /** read file in Junit from /src/main/resources/ **/
/** inject this testList into ClassUnderTest **/
fixture.setFileContent(testList );
/** then continue testing the actual method that needs to be tested **/
assertNotFalse(fixture.workOnFile());
}
为此,我必须更改需要测试的实际类才能注入测试文件读取。大致如下:
public class ClassUnderTest(){
public List<String> processFile(String fileName){
String localPath = FileSystems.getDefault().getPath(".").toAbsolutePath() + fileName;
}
/** new method used in junit to inject to **/
public void setFileContent(List<String> input){
this.input = input;
}
/** modify this method first check if injected arraylist not null **/
public boolean workOnFile(){
List<String> records;
if(this.input == null){
/** in actual runs this block will execute **/
this.input = processFile("abc.txt");
}
// additional logic
}
}
这是正确的方法吗? 我不知何故觉得我在弄乱代码以使其更易于测试? 这甚至是正确的方法吗?
一个简单的解决方案:更改接口以使其易于测试。
意义:
- 有一个方法将文件名放在"本地路径中"(与
processFile()
方法生成该文件名的方式相同 - 然后将该操作的结果传递给
processFile()
方法。
换句话说:您的代码将该方法限制为始终计算完整路径本身。这使得它真的很难控制,因此也很难测试。
因此:将您的问题剖析为尽可能小的部分。
然后你只需要测试:
- 您的新方法
Path getLocalPathFor(String fileName)
执行它应该做的事情 - 然后,您的方法
processFile(Path absFilePath)
执行它需要执行的操作(现在,您可以使用位于任何地方的路径来测试该方法,而不仅仅是在本地目录中(