Export to GitHub

mockito - issue #14

NPE on verification when multiple threads used


Posted on Jun 25, 2008 by Massive Monkey

I am getting a null pointer in my verify step. I get it from something like verify(mock, times(2).myMethod()

main test thread: init mocks stub what is needed kick of two threads

in the two threads execute myMethod()

back in main thread wait for the threads to day verify myMethod()

Stack trace:

java.lang.NullPointerException at org.mockito.internal.invocation.Invocation.isToString(Invocation.java: 181) at org.mockito.internal.verification.RegisteredInvocations $RemoveToString.isOut(RegisteredInvocations.java:33) at org.mockito.internal.verification.RegisteredInvocations $RemoveToString.isOut(RegisteredInvocations.java:31) at org.mockito.internal.util.ListUtil.filter(ListUtil.java:15) at org.mockito.internal.verification.RegisteredInvocations.getVerifiableInvocations(RegisteredInvocations.java: 28) at org.mockito.internal.verification.VerifyingRecorder.getRegisteredInvocations(VerifyingRecorder.java: 35) at org.mockito.internal.verification.VerifyingRecorder.verify(VerifyingRecorder.java: 47) at org.mockito.internal.MockHandler.intercept(MockHandler.java:73) at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java: 45) at com.sonicsw.esb.service.common.ramps.IDataSink$$EnhancerByCGLIB$ $413fdc72.createSinkConnection(<generated>) at RampTest.testUnblock(RampTest.java:326)

Comment #1

Posted on Jun 25, 2008 by Massive Monkey

Tried to reproduce it but everything works correctly. Can you submit more code describing the problem?

Here is how I tried to reproduce it:

public interface Foo {
    String myMethod();
}

@Test
public void shouldAllowVerifyingInThreads() throws Exception {
    final Foo foo = mock(Foo.class);

    stub(foo.myMethod()).toReturn("hello!");

    Thread threadOne = new Thread() {
        public void run() {
            foo.myMethod();
        }
    };

    Thread threadTwo = new Thread() {
        public void run() {
            foo.myMethod();
        }
    };

    threadOne.start();
    threadTwo.start();

    threadOne.join();
    threadTwo.join();

    verify(foo, times(2)).myMethod();
}

Comment #2

Posted on Jun 25, 2008 by Quick Bird

Here is a reproducible testcase:

package com.sonicsw.esb.service.common.ramps;

import static org.mockito.Mockito.*;

import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations.Mock;

import junit.framework.TestCase;

public class MockitoTest extends TestCase { public interface Foo { String myMethod(Object[] _args); }

@Mock private Foo foo;

@Override protected void setUp() throws Exception { super.setUp(); MockitoAnnotations.initMocks(this); }

public void testShouldAllowVerifyingInThreads() throws Exception { stub(foo.myMethod(isA(Object[].class))).toReturn("hello!"); // simulate 2 listener threads final Thread[] listeners = new Thread[3]; for (int i = 0; i < listeners.length; i++) { (listeners[i] = new Thread() { @Override public void run() { foo.myMethod(new Object[1]); try { Thread.sleep(100); } catch (InterruptedException e) { // ignore } } }).start(); } try { Thread.sleep(280); } catch (final InterruptedException e) { fail(); } for (int i = 0; i < listeners.length; i++) { try { listeners[i].join(); } catch (final InterruptedException e) { fail(); } } verify(foo, times(listeners.length)).myMethod(isA(Object[].class)); } }

It fails 9 out of 10 times.

The key issues is the use if an Object[] with null items and the use of more than one thread.

Cheers Thomas

Comment #3

Posted on Jun 25, 2008 by Massive Monkey

Fixed in trunk. Snapshots are downloadable here:

http://hudson.ramfelt.se/job/Mockito/

Comment #4

Posted on Apr 19, 2009 by Massive Monkey

(No comment was entered for this change.)

Status: Fixed

Labels:
Type-Defect Priority-High Milestone-Pre1.7