Question

I would like to test the following class:

public class TestClass {
    private OuterClass client;

    public TestClass(int v1, String v2){
        this.client = new OuterClass.FinalClass(v1, v2).build();
    }

    public boolean doAThing(){
        return this.client.respond();
    }
}

I am using an external library that looks something like this:

public class OuterClass{
    private int var1;
    private String var2;

    private OuterClass(int v1, String v2){
        this.var1 = v1;
        this.var2 = v2;
    }

    public static final class FinalClass{
        private int v1;
        private String v2;

        public FinalClass(int v1, String v2){
            this.v1 = v1;
            this.v2 = v2;
        }

        public OuterClass build(){
            return new OuterClass(this.v1, this.v2);
        }
    }

    public boolean respond(){
        throw new IllegalStateException("I'm real and shouldn't be!");
    }
}

My test code looks like this:

import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({OuterClass.class, OuterClass.FinalClass.class})
    public class TestTest {

        @Test
        public void test() throws Exception{
            PowerMockito.mockStatic(OuterClass.FinalClass.class);
            OuterClass.FinalClass mockFinal = 
                    PowerMockito.mock(OuterClass.FinalClass.class);
            OuterClass mockOuter = PowerMockito.mock(OuterClass.class);
            PowerMockito.whenNew(OuterClass.FinalClass.class)
                    .withAnyArguments()
                    .thenReturn(mockFinal);
            PowerMockito.when(mockFinal.build()).thenReturn(mockOuter);
            Mockito.when(mockOuter.respond()).thenReturn(true);

            TestClass t = new TestClass(1, "HALP");
            assertTrue(t.doAThing());
        }

    }

I would expect this test to pass, but instead it fails with an IllegalStateException. It seems instead of building a mock OuterClass from a mock FinalClass like I expect, it creates a real one, seemingly contrary to my whenNew directive. I am new to Mockito and PowerMock, and I'm sure I'm missing something basic. Still, I've tried solutions from every related question I can find on SO, and none have worked. Anyone willing to help?

Was it helpful?

Solution

You also need to prepare any class which creates a class you are trying to mock. That is, your annotation should be:

@PrepareForTest({
        OuterClass.class,
        OuterClass.FinalClass.class,
        TestClass.class})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top