0

I would like to mock a File and FileInputStream Object for an JUnit test.

Let us say we are having a Parser. From outside the Parser is just accessible via the parse(File myFile) method. The other methods like readMyStream....are private.

Example Code:

public class Parser {

   public HashMap<String, String> parse(File myFile) throws Exception {
         HashMap<String, String> myConfig;
         Config config;

         try {
             //this line gives me a headache
             FileInputStream myFileInputStream = new FileInputStream(myFile);

             configStream = readMyStream(myFileInputStream);
               ..........
         } catch (FileNotFoundException e) {
                throw e;
         }
         return myConfig;
   }
   //reads the stream 
   private Config readMyStream(FileInputStream myFileInputStream) {
      Config config;    

      ...JDOM stuff....    

      return config;
   }
}

The problems I face:

  • how to assert a File Object an FileInputStream (PowerMockito) like this File belongs to this FileInputStream with the following content
  • how to mock a private method (Mockito/PowerMockito)

an example of the Mocking/not working :)....

public class ParserTest {

   @Test
   public final void testParse() {
      File MOCKEDFILE = PowerMockito.mock(File.class);
      PowerMockito.when(MOCKEDFILE.exists()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.isFile()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.isDirectory()).thenReturn(false);
      PowerMockito.when(MOCKEDFILE.createNewFile()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.length()).thenReturn(11111111L);

      //what about the path of MOCKEDFILE which isn't existing
      PowerMockito.when(MOCKEDFILE.getPath()).thenReturn(?????);

      //how to assign a File an FileInputStream? (I thought something like)
      PowerMockito.mockStatic(FileInputStream.class);
      FileInputStream MOCKEDINPUTSTREAM = PowerMockito.mock(FileInputStream.class);
      PowerMockito.whenNew(FileInputStream.class).withArguments(File.class).thenReturn(MOCKEDINPUTSTREAM);

      //how to mock the private method readMyStream
   }
Funky Monkey
  • 87
  • 1
  • 2
  • 7

1 Answers1

4

Rather than mocking File, I would suggest using the TemporaryFolder Rule and create / not create the file as appropriate.

In my previous projects, we have written a FileInputStreamSupplier class that is used to create a FileInputStream. This class can then be mocked to provide a mocked FileInputStream to allow for testing behavior. Generically, you could have your class take a Supplier<FileInputStream> (using Guava) and mock that.

John B
  • 32,493
  • 6
  • 77
  • 98
  • could you please post an example code...I don't understand how the JUnit TemporaryFolder Rule should be related to my question. – Funky Monkey Oct 18 '12 at 09:00
  • You can use `TemporaryFolder` to create a `File` at runtime that matches the needs of the test, be it that the file exists (create it), has a particular name, extension, size, etc. Whan scenario are you attempting to test that would not be testable using this in conjunction with a `Supplier`? – John B Oct 18 '12 at 10:20
  • I could write something like `@Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); @Test public void testParse_xyas() { File tmpFile = tmpFolder.newFile(FILENAME); //now how to assert my tmpFile an InputStream?? }..` – Funky Monkey Oct 18 '12 at 12:47
  • What do you mean be `assert my tmpFile an InputStream`? The file is not an InputStream. The InputStream will be created around the file in the line `new FileInputStream(file)`. If you need to mock `FileInputStream`, again use the Supplier I mention above. – John B Oct 18 '12 at 12:54
  • Find this link pretty useful: [JUnit Rule Entity Manager](http://www.robert-franz.com/2013/03/26/junit-rule-entity-manager/) – Jing Li Jun 19 '14 at 14:52