Mocking static initialisers

67 views
Skip to first unread message

GeoffH

unread,
Nov 17, 2009, 12:45:02 PM11/17/09
to PowerMock
I have a legacy class that I am trying to mock
This class has some static initialisers, one of which causes a problem
when trying to mock:

The classes look approximately like:

package my.pkg;
public Class ClassWithStaticInitialiser {

private static ClassWithProblemStaticInitialiser aField =
new ClassWithProblemStaticInitialiser();

// other fields, constructor and methods
}

package my.pkg;
Class ClassWithProblemStaticInitialiser {

private static final String PACKAGE_LEVEL =
my.pkg.ClassWithProblemStaticInitialiser.class.getPackage().getName
();

// other fields, constructor and methods
}


I've set up some tests and attempted to run them in both Eclipse and
under Maven 2
I created a mock for ClassWithProblemStaticInitialiser along the
lines:

suppress(field(ClassWithProblemStaticInitialiser.class,
"PACKAGE_LEVEL"));
suppress(constructor(ClassWithProblemStaticInitialiser.class));
mockClassWithProblemStaticInitialiser =
PowerMockito.mock(ClassWithProblemStaticInitialiser.class);
PowerMockito.whenNew(ClassWithProblemStaticInitialiser.class).
withNoArguments().thenReturn
(mockClassWithProblemStaticInitialiser);

The results are different in Eclipse and Maven 2, but they are both
due to a NullPointerException
Under Maven 2 this occurs in the line
mockClassWithProblemStaticInitialiser =
PowerMockito.mock(ClassWithProblemStaticInitialiser.class);

and this is because of the static initialiser:
private static final String PACKAGE_LEVEL =
my.pkg.ClassWithProblemStaticInitialiser.class.getPackage().getName
();

- it turns out that
my.pkg.ClassWithProblemStaticInitialiser.class.getPackage()
is null at the point at which the mock is attempted


Has anyone come across anyhing like this and have a solution
- these are legacy classes, so I need to try and leave them as they
are

GeoffH

GeoffH

unread,
Nov 18, 2009, 4:42:01 AM11/18/09
to PowerMock
There is a difference between Eclipse and Maven
- but it depends on how I create the mocks

If I just create a mock for ClassWithStaticInitialiser, without first
attemtpting to create a mock for the static initialiser within this
class, then the test in Eclipse runs and passes

However, the same test in Maven throws a
<error
type="java.lang.NoClassDefFoundError">java.lang.NoClassDefFoundError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at javassist.runtime.Desc.getClassObject(Desc.java:43)
at javassist.runtime.Desc.getClassType(Desc.java:152)
at javassist.runtime.Desc.getType(Desc.java:122)
at javassist.runtime.Desc.getType(Desc.java:78)
at my.pkg.ClassWithStaticInitialiser.&lt;clinit&gt;
(ClassWithStaticInitialiser.java:49)

And line 49, is
private static ClassWithProblemStaticInitialiser aField =
new ClassWithProblemStaticInitialiser();

I don't really care about creating a mock for
ClassWithProblemStaticInitialiser
- as long as I can create a mock for ClassWithStaticInitialiser

But how is Eclipse treating this differently to Maven ?
Any suggestions or insight welcome

GeoffH

Johan Haleby

unread,
Nov 18, 2009, 6:13:55 AM11/18/09
to powe...@googlegroups.com
suppress(field(..)) only suppress the field when you read it. It still gets initialized. If you want to suppress the static initializer of a class you should use the @SuppressStaticInitializerFor(..) annotation, see the documentation at SuppressUnwantedBehavior (look for suppress static initializer).

/Johan

--

You received this message because you are subscribed to the Google Groups "PowerMock" group.
To post to this group, send email to powe...@googlegroups.com.
To unsubscribe from this group, send email to powermock+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/powermock?hl=.



GeoffH

unread,
Nov 18, 2009, 6:54:04 AM11/18/09
to PowerMock
Johan,

The @SuppressStaticInitializerFor worked perfectly

My task was to get a representative existing test running with
PowerMock / Mockito
- and that is now working
Thanks for this response in particular and all your other responses

I still have a few issues that I have to address, but at the moment
they are not related to PowerMock / Mockito

GeoffH

On Nov 18, 11:13 am, Johan Haleby <johan.hal...@gmail.com> wrote:
> suppress(field(..)) only suppress the field when you *read* it. It still
> gets initialized. If you want to suppress the static initializer of a class
> you should use the @SuppressStaticInitializerFor(..) annotation, see the
> documentation at
> SuppressUnwantedBehavior<http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior>(look
> for suppress static initializer).
>
> /Johan
>
> > powermock+...@googlegroups.com<powermock%2Bunsu...@googlegroups.com>
> > .

Johan Haleby

unread,
Nov 18, 2009, 7:15:55 AM11/18/09
to powe...@googlegroups.com
Glad to hear that you got it working :)

To unsubscribe from this group, send email to powermock+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages