我有一个类CollectionObject,它创建一个ArrayList。
public class CollectionObject {
private List<String> collectionObject;
public CollectionObject() {
collectionObject = new ArrayList<String>();
}
public List<String> getCollectionObject() {
return collectionObject;
}
public void add(final String stringToWrite) throws VerifyException {
collectionObject.add(stringToWrite);
}
}
还有另一个类,它接受类CollectionObject并使用它将文件的内容写入类CollectionObject。
public class ReaderFileWriterObjectService {
private BufferedReader bufferedReader;
private CollectionObject collectionObject;
private String line;
public CollectionObject getCollectionObjectAfterWritingFromAFile(final File file)
throws VerifyException, IOException {
collectionObject = new CollectionObject();
bufferedReader = new BufferedReader(new FileReader(file));
while ((line = bufferedReader.readLine()) != null) {
collectionObject.add(line);
}
bufferedReader.close();
return collectionObject;
}
如何测试和模拟类ReaderFileWriterObjectService的方法?
答案 0 :(得分:4)
您无法测试依赖java.io.File
的API;此类无法进行可靠的单元测试(即使它在JDK级别上甚至不是final
)。
但是新的文件系统API并不是这种情况,它出现在Java 7中。
也称为JSR 203,此API为任何提供&#34;文件系统对象的存储介质提供统一的API&#34;。
短篇小说:
FileSystem
上的资源获取路径,您可以使用Paths.get()
; 简而言之,在您的API 和测试用例中,您应该使用Path
,而不是File
。如果要测试与某些文件系统资源相关的任何内容,请使用JDK的Files
类来测试Path
个实例。
您可以从主要的基于磁盘的文件系统中创建FileSystem
。建议:使用this。
答案 1 :(得分:2)
我正在做同样的事情,以下想法正在发挥作用, 我希望这对你也有用,
@InjectMocks
private CollectionObject collectionObject;
@Test
public void getCollectionObjectAfterWritingFromAFile() throws Exception {
CollectionObject expectedObject =new CollectionObject();
List<String> expectedList=new ArrayList<String>();
expectedList.add("100");
CollectionObject resultObject =new CollectionObject();
BufferedReader reader=new BufferedReader(new StringReader("100"));
PowerMockito.mock(BufferedReader.class);
PowerMockito.mock(FileReader.class);
PowerMockito.whenNew(FileReader.class).withArguments("test10.csv").thenReturn(null);
PowerMockito.whenNew(BufferedReader.class).withArguments(null).thenReturn(reader);
resultObject=collectionObject.getCollectionObjectAfterWritingFromAFile( "test10.csv");
assertEquals(expectedObject ,resultObject );
}
答案 2 :(得分:1)
您可以使用JUnit的TemporaryFolder创建文件,并将资源中的内容复制到该文件中。
public YourText {
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test
public void checkSomething() throws Exception {
InputStream resource = getClass().getResourceAsStream("/your/resource");
File file = folder.newFile();
Files.copy(resource, file);
ReaderFileWriterObjectService service = ...
CollectionObject collection = service
.getCollectionObjectAfterWritingFromAFile(file);
...
}
答案 3 :(得分:0)
你做不到。你很幸运。更好的设计会接受Java 7 java.nio.file.FileSystem
和Path
,它们可以换出来进行测试实施,例如: https://github.com/google/jimfs
答案 4 :(得分:0)
好的,首先让我们考虑你想测试什么?如果它是单元测试,那么你不想测试集成,如与文件系统的通信,你必须测试自己的逻辑,你的逻辑是这样的: 1)使用文件系统集成从文件中读取下一行 2)将此行添加到我的对象
中第二步你不应该测试,因为这个方法太容易破解。您无法测试的第一步导致它执行集成调用。所以我认为你不需要进行单元测试
但是如果你的逻辑会更复杂,那么你可以在测试中引入界面包装并模拟它:
public interface FileWrapper{
public String readLine();
public void close();
}
public class FileWrapperImpl implements FileWrapper{
private File file;
private BufferedReader reader;
public FileWrapperImpl (File file){
this.file = file;
this.reader= ...
}
public String readLine(){
return reader.nextLine();
}
}
然后是您的ReaderFileWriterObjectService:
public CollectionObject getCollectionObjectAfterWritingFromAFile(FileWrapper wrapper)
CollectionObject collectionObject = new CollectionObject();
while ((line = wrapper.readLine()) != null) {
collectionObject.add(line);
}
wrapper.close();
return collectionObject;
}
现在您可以轻松地模拟FileWrapper进行测试并将其传递给您的服务
答案 5 :(得分:0)
我建议更改API以接受Reader或BufferedReader - 这些可以被模拟。使用工厂隐藏文件的依赖关系。