Reputation: 1907
I have a class CollectionObject which creates a 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);
}
}
There is another class which takes in the class CollectionObject and uses it to write the contents of the file to the class 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;
}
How to Test and Mock the method of the class ReaderFileWriterObjectService?
Upvotes: 3
Views: 11861
Reputation: 316
I am doing the same thing, And the following idea is working, I hope this will work for u too,
@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 );
}
Upvotes: 2
Reputation: 121710
Let me complement on @LouisWasserman's answer.
You just cannot test APIs which rely on java.io.File
; this class cannot be reliably unit tested (even though it is not even final
at the JDK level).
But this is not the case with the new filesystem API, which appeared with Java 7.
Also known as JSR 203, this API provides a unified API to any storage medium providing "filesystem objects".
Short story:
FileSystem
, you can use Paths.get()
;In short, in your API and test case, you should use Path
, not File
. And if you want to test anything related to some filesystem resource, use the JDK's Files
class to test Path
instances.
And you can create FileSystem
s out of your main, disk based, file system. Recommendation: use this.
Upvotes: 4
Reputation: 24520
You can use JUnit's TemporaryFolder for creating a file and copy the contents from a resource to it.
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);
...
}
Upvotes: 1
Reputation:
I'd suggest changing the API to accept Reader or BufferedReader - those can be mocked. Hide the dependency on file with a factory.
Upvotes: 0
Reputation: 338
Okay, at first lets consider what do u want to test? If it is unit test then u dont want to test integrations like communications with filesystem, you have to test your own logic and your logic is something like: 1) Read next line from file using file system integration 2) add this line into my object
The second step you should not test because this method is too easy to break. The first step you can't test cause it performs integrations call. So i don't think that here u need a unit test
But if your logic will be more complicated, then you can introduce interface wrapper and mock it in your test:
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();
}
}
And then your ReaderFileWriterObjectService:
public CollectionObject getCollectionObjectAfterWritingFromAFile(FileWrapper wrapper)
CollectionObject collectionObject = new CollectionObject();
while ((line = wrapper.readLine()) != null) {
collectionObject.add(line);
}
wrapper.close();
return collectionObject;
}
And now you can easily mock FileWrapper for test and pass it to your service
Upvotes: 0
Reputation: 198093
You cannot. You're pretty much out of luck. A better design would accept a Java 7 java.nio.file.FileSystem
and a Path
that could be swapped out for a test implementation, e.g. https://github.com/google/jimfs.
Upvotes: 0