3

I have a public outer class with a protected static inner class that I need to mock out for unit testing. We are using Mockito and PowerMockito but I have not been able to find anything in this vein during my searches. Does anyone have any ideas? Refactoring the inner class to be outside of the class and be public or anything of the sort is out of the question as of now as well.

1 Answers1

6

Given a structure similar to

public class OuterClass {

    public OuterClass() {
        new InnerClass();
    }

    protected static class InnerClass {
        public InnerClass() {
            throw new UnsupportedOperationException("Muahahahaha!"); // no touchy touchy!
        }
    }
}

... you should be able to do the following

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

import static org.junit.Assert.assertNotNull;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.whenNew;

@RunWith(PowerMockRunner.class) // delegate test running to PowerMock
@PrepareForTest(OuterClass.class) // mark classes for instrumentation so magic can happen
public class InnerClassTest {

    @Test
    public void shouldNotThrowException() throws Exception { // oh, the puns!
        // make a mockery of our inner class
        OuterClass.InnerClass innerClassMock = mock(OuterClass.InnerClass.class);

       // magically return the mock when a new instance is required
       whenNew(OuterClass.InnerClass.class).withAnyArguments().thenReturn(innerClassMock);

        // yey, no UnsupportedOperationException here!
        OuterClass outerClass = new OuterClass();
        assertNotNull(outerClass);
    }
}
Morfic
  • 15,178
  • 3
  • 51
  • 61
  • I did see this. I apologize for not getting back to you with this. This actually did not work for the particular test case I was working with. Legacy code is tightly coupled and required a few extra things to get it to where it needed to be. That being said, this example helped me with a completely different test case I had right after that so I greatly appreciate your help! Thanks! – Nicholas Pierce Feb 24 '16 at 02:35
  • @NicholasPierce Great news! You're more than welcome to update the question illustrating your real issue, given it's a bit different than what I imagined, post and accept your answer as the correct one. This way anyone else who'll end up in your situation will know how to bypass it, and the rest of us might actually learn something new. Cheers :-) – Morfic Feb 24 '16 at 08:30
  • I'm trying to do that right now. This is production code so I must be careful about what does and doesn't get posted for obvious reasons. Also, the class is seriously out of control. My direct senior and I are contemplating just taking a few days to refactor it for the sake of posterity so i'll make so to log what it looks like now at least and if I can find a decent way of doing it, i'll post the example and result. Thanks! – Nicholas Pierce Feb 24 '16 at 16:04
  • Tried it out! It works as demonstrated in the snippet, where a mock of InnerClass is returned within shouldNotThrowException. I am wondering why this doesn't work, if a mock of the static inner class is needed elsewhere, in a different class for instance...? – crishushu Apr 07 '21 at 14:22