1

Hello anyone would know how to spy a class that is extending ArrayBlockingQueue? For example I want to spy the following MyBufferQueue class

public class MyBufferQueue extends ArrayBlockingQueue<MyBuffer> {}

Inside of ArrayBlockingQueue class that belongs to java library, there is this method:

public void put(E e) throws InterruptedException {
   Objects.requireNonNull(e);
   final ReentrantLock lock = this.lock;
   lock.lockInterruptibly();
   try {
       while (count == items.length)
       notFull.await();
       enqueue(e);
   } finally {
       lock.unlock();
   }
}

The problem I have is that when I am spying the class MyBufferQueue and during the test when it is accessed the method ArrayBlockingQueue.put(E e), I am getting a NullPointerException in this.lock, when it is supposed that it shouldn't be null as I am creating a new instance of MyBufferQueue in my test, and when creating the new instance the fields inside of ArrayBlockingQueue should be instantiated too as ArrayBlockingQueue is the super class.

This is how would look the test method:

@Test
void testMyBuffer() {
    MyBufferQueue queue = spy(new MyBufferQueue(1));
    doNothing().when(queue).retryAll();
    
    queue.consumeFullQueue();

    verify(queue).retryAll();
}

For spying I am using Mockito version mockito-core:4.7.0 and I am using Java 18.

Thanks in advance.

1 Answers1

0

I've had the same problem recently, and it's caused by how Java 17 and up (possibly earlier, but at least after Java 11) works in combination with Mockito. Instance fields of spied objects remain null.

The solution is very simple - replace mockito-core with mockito-inline. Same groupId, same version, just a different artifactId.

Rob Spoor
  • 6,186
  • 1
  • 19
  • 20
  • Thanks! Just by adding `mockito-inline` looks to work for me now, now when spying `MyBufferQueue`, the fields of the super class are not giving me now `NullPointerException`, and now the test is passing. What I couldn't do is to replace `mockito-core` with `mockito-inline`, maven was including me `mockito-core` even after adding `` in pom for that dependency. So I have included both of them in the pom file. – user3419082 Aug 22 '22 at 08:58
  • Continuing my previous comment, following this [page](https://www.davidvlijmincx.com/posts/writing_higher_quality_tests_with_mockitos_inline_mock_maker/), they explain that it can be added Mockito's inline by adding `mockito-core` and `mockito-inline` dependencies in your pom, it looks like it is not needed to replace it with `mockito-core`, both of them have to be as dependencies in your pom. – user3419082 Aug 22 '22 at 09:01
  • @user3419082 you shouldn't exclude `mockito-core`, it's still needed. As you found out, if you include `mockito-inline` you transitively include `mockito-core`, and that's just fine. I just prefer to not duplicate version numbers. Sorry for the confusion. – Rob Spoor Aug 22 '22 at 13:30