PowerMock not mocking code in clinit of base class of mocked class

324 views
Skip to first unread message

KARR, DAVID

unread,
May 16, 2013, 7:54:24 PM5/16/13
to powe...@googlegroups.com
I'm trying to build a unit test for a class that is really presenting a challenge. It has static variables that are initialized by calls to other static methods, and this is also done in the base class of a class I'm trying to mock.

So, for instance, the class I'm trying to test is called "FooUtils". It has a "private static final" variable (call it "itemManager", of type "ItemManager") that is initialized by a call to a static method in another class (call it "Bar"). That class the static method is in has a base class (call it "GenericContext") which has a "private static" of type "java.util.ResourceBundle".

So, to attempt to handle all this, here are my class annotations:

@RunWith(PowerMockRunner.class)
@PrepareForTest({Bar.class, GenericContext.class, ResourceBundle.class})

And here is my @Before code:

@Mock
private Bar bar;
@Mock
private ItemManager itemManager;
@Mock
private ResourceBundle resourceBundle;

@Before
public void setup() {
PowerMockito.mockStatic(Bar.class);
PowerMockito.mockStatic(GenericContext.class);
PowerMockito.mockStatic(ResourceBundle.class);
when(Bar.getGlobalBar()).thenReturn(bar);
when(bar.resolveName(anyString())).thenReturn(itemManager);
when(ResourceBundle.getBundle(anyString())).thenReturn(resourceBundle);
}

I set a breakpoint on the initialization line in FooUtils for "itemManager", which calls "Bar.getGlobalBar().resolveName(...)". When I ran my test, it hit this line, and then when I continued, it didn't use the mocked instances, it apparently went into the Bar, GenericContext, and ResourceBundle code, and ending up throwing an exception.

I'm not sure what else I should be doing.


Matt Lachman

unread,
May 16, 2013, 8:33:53 PM5/16/13
to powe...@googlegroups.com
Take a look at the docs for @SuppressStaticInitializationFor. That combined with a sprinkling of Whitebox calls to set static variables up with canned data or mock objects has worked pretty well for me.

I'm on my mobile right now, otherwise I'd provide links/examples.

Matt
--
You received this message because you are subscribed to the Google Groups "PowerMock" group.
To unsubscribe from this group and stop receiving emails from it, send an email to powermock+...@googlegroups.com.
To post to this group, send email to powe...@googlegroups.com.
Visit this group at http://groups.google.com/group/powermock?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


KARR, DAVID

unread,
May 17, 2013, 1:31:16 AM5/17/13
to powe...@googlegroups.com

Ok, I think I’ve gotten past this particular problem, but it’s still not quite right.

 

This is what I’m left with at the beginning of the class:

 

@RunWith(PowerMockRunner.class)

@PrepareForTest({Bar.class, GenericContext.class, ResourceBundle.class})

@SuppressStaticInitializationFor({"bar.GenericContext", "bar.Bar"})

public class RTIUtilsTest {

    private RTIUtils    rtiUtils    = new RTIUtils();

 

    @Mock

    private Bar bar;

    @Mock

    private ItemManager  itemManager;

    @Mock

    private ResourceBundle      resourceBundle;

   

    @Before

    public void setup() {

        PowerMockito.mockStatic(Bar.class);

        PowerMockito.mockStatic(GenericContext.class);

        PowerMockito.mockStatic(ResourceBundle.class);

        suppress(constructor(GenericContext.class));

        suppress(constructor(Bar.class));

        PowerMockito.when(Bar.getGlobalBar()).thenReturn(bar);

        when(bar.resolveName(anyString())).thenReturn(itemManager);

        PowerMockito.when(ResourceBundle.getBundle(anyString())).thenReturn(resourceBundle);

    }

 

Now I’m getting a NPE inside the “Bar.getGlobalBar()” method, because the code references an instance variable I haven’t wired in.  As far as I can tell, it shouldn’t be getting into the method, because I’ve mocked the static methods of “Bar”, and I have a when clause for that method.  Why is it getting into the method?

KARR, DAVID

unread,
May 17, 2013, 9:57:44 AM5/17/13
to powe...@googlegroups.com

I think I figured this out.  I neglected to suppress static initialization for my class under test, which also defines statics and initializes them with calls to static methods.

Reply all
Reply to author
Forward
0 new messages