2

So I'm trying to mock a FileOutputStream but it fails with a NullPointer Exception because I can not mock the method isInvalid from File. First the Code i want to mock:

FileOutputStream fos    = null;
fos = createFileOutputStream( file )

...

public FileOutputStream createFileOutputStream( File clsFile ) throws FileNotFoundException
{
    return new FileOutputStream( clsFile );
}

My relating mocks:

File clsFile = Mockito.mock( File.class );
Mockito.when( clsUnitUnderTest.createNewFile( strTargetPath + "XXX" + strTargetFileName ) ).thenReturn( clsFile );
Mockito.when( clsFile.exists() ).thenReturn( true );
Mockito.when( clsFile.createNewFile() ).thenReturn( true );
Mockito.when( clsFile.renameTo( new File( strTargetPath + strTargetFileName ) ) ).thenReturn( false );
Mockito.when( clsFile.getPath() ).thenReturn( strTargetPath + "XXX" + strTargetFileName );

// Mockito.when( clsFile.isInvalid ).thenReturn( false ); not working because isInvalid is final!!

FileOutputStream clsFileOutputStream = Mockito.mock( FileOutputStream.class );
Mockito.when( clsUnitUnderTest.createFileOutputStream( clsFile ) ).thenReturn( clsFileOutputStream );

I know there is no way to mock the final method isInvalid. But is there another way to fix this without using PowerMokito?

I also tried using spy instead of mock for the clsFileOutputStream, but this doesn't work because there's no constructor with 0 args.

Ganymed
  • 79
  • 1
  • 2
  • 7
  • 2
    Why are you writing tests for well-behaved JDK classes in the first place? – M. Prokhorov Apr 04 '17 at 13:14
  • @M.Prokhorov I'm not testing the File or the FileOutputStream. I use them in my Program and want to mock them because they do well-behave. Testing the other code is more important and therefore I need the possibility to easily manipulate the File and the FileOutputStream. – Ganymed Apr 04 '17 at 13:25
  • You test seem to rely on ability to mock things that aren't really mockable in this case. I might suggest either writing integration tests for that part, or refactor so you don't have to mock half of your JDK in the process. – M. Prokhorov Apr 04 '17 at 13:43
  • Very related: [Mocking Files in Java - Mock Contents - Mockito](http://stackoverflow.com/q/17681708/1426891) – Jeff Bowman Apr 04 '17 at 17:10

1 Answers1

0

you can try to replace FileOutputStream with OutputStream

Instead of

 public class MyClass {
    public FileOutputStream createFileOutputStream( File clsFile ) throws FileNotFoundException
    {
        return new FileOutputStream( clsFile );
    }

    void doSomething(File file) {
        // process file 
        ....
        FileOutputStream str = createFileOutputStream(file);

        // process stream
    }
 }

you have

 public class MyClass {
    public OutputStream createFileOutputStream( File clsFile ) throws FileNotFoundException
    {
        return new FileOutputStream( clsFile );
    }

    void doSomething(File file) {
        // process file 
        ....
        OutputStream str = createFileOutputStream(file);
        doSomething(str);
    }

    void doSomething(OutputStream stream) {
        // process stream
    }

 }

It is easier to mock OutputStream and you can seperate testing of file processing from testing stream processing

k3b
  • 14,517
  • 7
  • 53
  • 85