NullPointerException in stubbed method of mocked class

3,657 views
Skip to first unread message

GeoffH

unread,
Nov 12, 2009, 10:55:04 AM11/12/09
to PowerMock
I'm getting a NullPointerException for a method that I have stubbed in
a mocked class
The odd thing is that I do not believe this is the first call to the
stubbed method
- if I remove the method stubbing then the test fails in a different
place where it had tried to make a call to the method (that was
previously stubbed) - and I do then get a null

It sort of seems like it is a response to a method that has not been
stubbed
However, I know that the stubbed method has been called many times
before I get the NPE
- and it is consistent: it null pointers every time at the same place

The class mock and stubbing looks like:

PowerMockito.mockStatic(ClassWithStaticMethod.class);

// set up expectations for
// ClassWithStaticMethod.decodeByteArray(ByteBuffer, boolean)
for (ByteBuffer buf : tcrDecodeList)
{
Mockito.when(ClassWithStaticMethod.decodeByteArray(buf, true)).
thenReturn(getMockCharBuffer(buf, mapping));
}

and I have the test prepared with
@PrepareForTest(ClassWithStaticMethod);

In the above
tcrDecodeList is a List<ByteBuffer>
getMockCharBuffer(buf, mapping) is a local method that takes a
ByteBuffer and String and returns a CharBuffer
- I've tested this method independently using the tcrDecodeList and I
never get a null returned

It's difficault to know how to debug this
- and I appreciate that without real code, it can be difficult to
make suggestions

What I'm looking for is some help / direction on how to track this
down
Any suggestions gratefully accepted

The List<ByteBuffer> has 68 entries
Some of the ByteBuffer are quite large - the max single underlying
byte array is 5300 bytes
The total number of bytes for all entries in the List exceeds 64K
- I know this because I was not able to statically initilise the data
in a class

Thanks

GeoffH

GeoffH

unread,
Nov 13, 2009, 5:53:49 AM11/13/09
to PowerMock
A bit of clarification and a bit of progress

Actually what is happening is the following:
A call to a stubbed method in a mocked class is returning a null value
object
When the returned object is accessed to get some data, the
NullPointerException occurs


I then did a test where I set an expectation with an explicit argument
value for a stubbed method
Then I called the stubbed method with some other argument
The stubbed method returned a null value


I also did a test setting an expectation on a stubbed method with a
long (>5000 bytes) ByteBuffer argument

PowerMockito.mockStatic(ClassWithStaticMethod.class);
Mockito.when(ClassWithStaticMethod.decodeByteArray(buf, true)).
thenReturn(getMockCharBuffer(buf, mapping));
CharBuffer expected = getMockCharBuffer(buf, mapping);
assertEquals("Unexpected", expected,
ClassWithStaticMethod.decodeByteArray(buf, true));

The test passed as expected


This implies
a) calling a stubbed method with an argument that has not been set up
will return default (0 / "" / null)
b) using a long expectation argument works fine
c) in my real test where a null is returned, the expectation has not
been set

However, c) is odd, because I definitely use the data (long
ByteBuffer) to set up the expectation

Thanks for reading and any suggestions

GeoffH

GeoffH

unread,
Nov 13, 2009, 8:49:04 AM11/13/09
to PowerMock
Johan,

I have the stack trace in Eclipse at the point at which I am just
about to get a null return from a stubbed method
Would any of these enable me to examine the state of the stubbed
method ?
i.e. to tell if the expectation has been set ?

Rerun
com.visaeu.rcs.application.cas.parser.TC05Test.testTCValidTransactionBatch
[JUnit]
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner at localhost:
3687
Thread [main] (Suspended (breakpoint at line 521 in BaseCommon))
BaseCommon.populateParserInternal(ByteBuffer, String) line: 521
BaseCommon.getRcsParsedBatch(Collection, ByteBuffer, boolean) line:
425
TCTransactionParser.parseBatch(ByteBuffer, ByteBuffer, int,
CASConstants$BatchType) line: 690
TCTransactionParser.parseBatch(ByteBuffer, ByteBuffer, int) line: 95
TCTransactionParser.parseBatch(ByteBuffer, ByteBuffer) line: 601
TC05Test.testTCValidTransactionBatch() line: 279
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 592
TestMethod.invoke(Object) line: 66
PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner
(PowerMockJUnit44RunnerDelegateImpl
$PowerMockJUnit44MethodRunner).runTestMethod() line: 322
MethodRoadie$2.run() line: 86
PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner
(MethodRoadie).runBeforesThenTestThenAfters(Runnable) line: 94
PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner
(PowerMockJUnit44RunnerDelegateImpl
$PowerMockJUnit44MethodRunner).executeTest(Method, Object, Runnable)
line: 309
PowerMockJUnit47RunnerDelegateImpl
$PowerMockJUnit47MethodRunner.executeTestInSuper(Method, Object,
Runnable) line: 112
PowerMockJUnit47RunnerDelegateImpl
$PowerMockJUnit47MethodRunner.executeTest(Method, Object, Runnable)
line: 73
PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner
(PowerMockJUnit44RunnerDelegateImpl
$PowerMockJUnit44MethodRunner).runBeforesThenTestThenAfters(Runnable)
line: 297
PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner
(MethodRoadie).runTest() line: 84
PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner
(MethodRoadie).run() line: 49
PowerMockJUnit47RunnerDelegateImpl
(PowerMockJUnit44RunnerDelegateImpl).invokeTestMethod(Method,
RunNotifier) line: 222
PowerMockJUnit47RunnerDelegateImpl
(PowerMockJUnit44RunnerDelegateImpl).runMethods(RunNotifier) line:
161
PowerMockJUnit44RunnerDelegateImpl$1.run() line: 135
ClassRoadie.runUnprotected() line: 34
ClassRoadie.runProtected() line: 44
PowerMockJUnit47RunnerDelegateImpl
(PowerMockJUnit44RunnerDelegateImpl).run(RunNotifier) line: 133
JUnit4TestSuiteChunkerImpl.run(RunNotifier) line: 112
PowerMockRunner(AbstractCommonPowerMockRunner).run(RunNotifier) line:
44
JUnit4TestMethodReference(JUnit4TestReference).run(TestExecution)
line: 38
TestExecution.run(ITestReference[]) line: 38
RemoteTestRunner.runTests(String[], String, TestExecution) line: 460
RemoteTestRunner.runTests(TestExecution) line: 673
RemoteTestRunner.run() line: 386
RemoteTestRunner.main(String[]) line: 196
Thread [ReaderThread] (Running)
C:\Program Files (x86)\Java\jdk1.5.0_21\jre\bin\javaw.exe (13 Nov 2009
13:40:18)

Thanks,

GeoffH

Johan Haleby

unread,
Nov 13, 2009, 9:32:52 AM11/13/09
to powe...@googlegroups.com
I don't know if I've understood everything correctly but at least I'll try to answer some of the questions:

a) This is how Mockito works, if you haven't specified anything explicitly it will stub the call and return a default value.
b) Ok, that's fine I guess!?
c) I suspect that it's not the same array instance that you expect that actually gets passed to the method when you execute the test. You need argument matchers to verify that. Look in the Mockito documentation on how to do that.

/Johan
Reply all
Reply to author
Forward
0 new messages