Ofek Regev
Ofek Regev

Reputation: 502

PowerMock with Mockito doesn't create mock for constructor invocations

I'm trying to use PowerMock with mockito to create mock each time any constructor of FileOutputStream is created but it seems to return a real instance instead of a mocked one.

My test class :

@RunWith(PowerMockRunner.class)
@PrepareForTest({FileOutputStream.class,FilesHelper.class})
public class FilesHelperTest {


@Test
public void createFileFromInputStream_validate_null_progress_subject_doesnt_throws_null_pointer() throws Exception {
    FileOutputStream fileOutputStream = Mockito.mock(FileOutputStream.class);
    PowerMockito.whenNew(FileOutputStream.class).withAnyArguments().thenReturn(fileOutputStream);
    File file = Mockito.mock(File.class);
    BufferedSource bufferedSource = Mockito.mock(BufferedSource.class);
    Mockito.doReturn(true).when(file).exists();
    Mockito.when(bufferedSource.read(Mockito.any(),Mockito.anyLong())).thenReturn(15L,-1L);
    FilesHelper.createFileFromInputStream(file,bufferedSource,8,null);
 }
}

My class under test -

public class FilesHelper {

/**
 * Creates a file out of an input stream wrapped by Okio's {@link BufferedSource}.
 * @param file a file to save the input to
 * @param bufferedSource the source input.
 * @param maxSize the maximum amount of bytes can be loaded to memory
 * @param progressUpdatePublisher an optional update publisher which notifies the writing progress
 * @return a {@link com.bonimoo.wominstaller.data.entities.BaseDownloadStatusDTO.Done} status with all the necessary information.
 * @throws IOException in case of errors while writing
 * @throws IllegalStateException when the file doesn't exists and cannot be created
 */
public static BaseDownloadStatusDTO.Done createFileFromInputStream(File file, BufferedSource bufferedSource, int maxSize, @Nullable PublishSubject<BaseDownloadStatusDTO> progressUpdatePublisher) throws IOException, IllegalStateException {
    if (!file.exists()) {
        Throwable cause = null;
        boolean created = false;
        try {
            created = file.createNewFile();
        } catch (IOException e) {
            cause = e;
        }
        if (!created) {
            throw new IllegalStateException("FilesHelper cannot create new file",cause);
        }
    }
    if (progressUpdatePublisher != null) {
        progressUpdatePublisher.onNext(new BaseDownloadStatusDTO.Started(file.getAbsolutePath()));
    }
    BufferedSink sink = Okio.buffer(Okio.sink(file));
    Buffer buffer = new Buffer();
    long counter = 0L;
    try {
        for (long readCount = bufferedSource.read(buffer, maxSize); readCount > -1 || bufferedSource.exhausted(); readCount = bufferedSource.read(buffer, maxSize)) {
            sink.writeAll(buffer);
            counter += readCount;
            if (progressUpdatePublisher != null) {
                progressUpdatePublisher.onNext(new BaseDownloadStatusDTO.Progress(counter,file.getAbsolutePath(),readCount));
            }
        }
    } finally {
        sink.flush();
        sink.close();
        buffer.close();
        bufferedSource.close();
    }
    return new BaseDownloadStatusDTO.Done(file);
 }
}

so when I'm creating the class I'm still getting the null pointer exception which thrown by the real constructor invocation

java.lang.NullPointerException
    at java.io.FileOutputStream.<init>(FileOutputStream.java:203)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
    at okio.Okio.sink(Okio.java:181)
    at com.bonimoo.wominstaller.data.helpers.FilesHelper.createFileFromInputStream(FilesHelper.java:49)
    at com.bonimoo.wominstaller.data.helpers.FilesHelperTest.createFileFromInputStream_validate_null_progress_subject_doesnt_throws_null_pointer(FilesHelperTest.java:36)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:326)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:310)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:298)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:218)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:160)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:134)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:136)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:117)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
    at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Upvotes: 0

Views: 673

Answers (1)

kswaughs
kswaughs

Reputation: 3087

FileOutputStream object is instantiated in okio.Okio.sink method.

So, add Okio.class in @prepareForTest.

Upvotes: 1

Related Questions