user2880391
user2880391

Reputation: 2791

Junit - mock a file

I'm trying to cover code that process a file. I'm trying to avoid using real file for tests, so I'm using Mockito. This is the code I'm trying to test:

try {
    byte[] data = Files.readAllBytes(((File) body).toPath());
    immutableBody = data;
    actualHeaderParams.put(HttpHeaders.CONTENT_LENGTH, (new Integer(data.length)).toString());
    contentType = MediaType.APPLICATION_OCTET_STREAM;
  }

I'm using mock file:

File mockedFile = Mockito.mock(File.class);

but I get an Exception on 'toPath'. So I added some path or null, but then again I get Exceptions since the file doesn't exist in the path.

when(mockedFile.toPath()).thenReturn(Paths.get("test.txt"));

getting:

com.http.ApiException: There was a problem reading the file: test.txt

Is there any way doing it without creating a real file for the test?

Upvotes: 2

Views: 20734

Answers (3)

Adam Siemion
Adam Siemion

Reputation: 16039

Since you want to mock reading of files I assume you have some logic in this class which you would like to test in isolation (without using actual files), therefore I suggest to:

Move the responsibility of reading files into a separate class, so instead of having:

byte[] data = Files.readAllBytes(((File) body).toPath());

interleaved with your business logic, have:

byte[] data = fileReader.read(body);

and fileReader will be an instance of your class with a very simple implementation along these lines:

class FileToBytesReader { 
  byte[] read(File file) throws IOException {
    return Files.readAllBytes(((File) body).toPath());
  }
}

then in your test you can subsitute fileReader with a mock on which you can set expectations.

If you are using Java 8 you do not have to create the FileToBytesReader class, but you can use java.util.Function:

Function<File, byte[]> fileReader = (file) -> {
  try {
    return Files.readAllBytes(((File) file).toPath());
  } catch (IOException e) {
    throw new UncheckedIOException(e);
  }
};

BTW. If you are working on a legacy code and you cannot change the production code, then you have to use PowerMock to mock this static method.

Upvotes: 6

LetsCode
LetsCode

Reputation: 198

Mock Files.readAllBytes() with Matchers.any() as arguments. and return a byte array.

Upvotes: 0

Plog
Plog

Reputation: 9622

I'm not sure there is an easy way but I might be wrong. You would probably need to mock the static Files.readAllBytes() method which you would need to use something like PowerMock to do. Or you could wrap this in a method which you can then mock the behaviour of:

 public byte[] getAllBytesWrapper(File body) {
     return Files.readAllBytes(body.toPath());
 }

and then have a mock for this method:

 when(classUnderTest.getAllBytesWrapper(any(File.class))).thenReturn("test".getBytes());

Upvotes: 0

Related Questions