Trying to mock java.io.DataInputStream.read

335 Views Asked by At

My application has a piece that does the following:

public ResultObject myMethod(DataInputStream inputStream, int objectLength) {
        byte[] buffer = new byte[objectLength];
        int bytesRead = inputStream.read(buffer);
    ...

However, based on a piece ahead of this, the amount of data read out of the inputStream does not necessarily match the object length - sometimes it is less if the object is very large (>150 MB). I cannot change the upstream part of the application so instead, I loop through until I have read objectLength number of bytes.

            while (bytesRead < objectLength) {
                //keep looping and adding to my output
            }

I am trying to unit test the logic inside the conditional loop and am having a lot of trouble. The closest question I found was this one, although this hasn't got me across the finish line: How to mock FileInputStream and other *Streams.

I don't want to create a real object that size so I was trying to simply mock the DataInputStream.read method and basically re-create the behavior with a smaller object. I was hoping I could return a real instance of the object with doReturn, but so far no dice.

@RunWith(PowerMockRunner.class)
@PrepareForTest(DataInputStream.class)
public void MyTestClass {
@Test
public void myTestMethod() {
    int objectLength = 1024;
    String testString = BytesDecoderSpec.generateRandomString(objectLength);
    int testStringLength = testString.length();
    DataInputStream stream = new DataInputStream(new ByteArrayInputStream(testString.getBytes()));
    MyRealClass realObject = new MyRealClass();

    final DataInputStream mockStream = PowerMockito.mock(DataInputStream.class);
    PowerMockito.whenNew(DataInputStream.class).withArguments(any()).thenReturn(mockStream);

    PowerMockito.doReturn(stream.read(new byte[testStringLength/2])).doReturn(stream.read(testStringLength - testStringLength / 2)).when(mockStream).read(any());
    ResultObject result = realObject.myMethod(mockStream, testStringLength);
}

When I do this, I get a NullPointerException on myMethod > inputStream.read. I also tried using spy instead, but it didn't work either:

DataInputStream mockStream = PowerMockito.spy(stream);
PowerMockito.doReturn(mockStream.read(new byte[testStringLength/2])).doReturn(mockStream.read(testStringLength - testStringLength / 2)).when(mockStream).read(any());

Am I going about this all wrong? Any guidance you can provide is really appreciated - thank you!

0

There are 0 best solutions below