Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito - Stubbing a method of an object that was returned by a mock object method

Let's say I have an mock object, and I don't want to stub any of it's methods, but I want to stub a method of an object it returns. For example,

when(mockObject.method1()).thenReturn(returnValue)

is how it's normally done, but I'm looking for,

when(mockObject.method1().method2()).thenReturn(returnValue)

Is that possible? I get a NullPointerException if I do that. Currently I have stub the first method to return a mock object, and then using that returned mock object, stub the second method. However, these temporary mock objects are useless to me and after chaining many methods together, that results in a lot of useless mock objects.

EDIT: Actually, it's possible that chaining works, but my objects are causing the NPE. This code (the first line) is causing a NPE:

when(graphDb.index().getNodeAutoIndexer()).thenReturn(nodeAutoIndexer);
when(graphDb.index().getRelationshipAutoIndexer()).thenReturn(relAutoIndexer);

But this code works:

IndexManager indexManager = mock(IndexManager.class);
when(graphDb.index()).thenReturn(indexManager);
when(indexManager.getNodeAutoIndexer()).thenReturn(nodeAutoIndexer);
when(graphDb.index().getRelationshipAutoIndexer()).thenReturn(relAutoIndexer);

So chaining didn't work for getNodeAutoIndexer() which returns an AutoIndexer object while it worked for getRelationshipAutoIndexer() which returns a RelationshipAutoIndexer. Both return values are mocked as follows:

nodeAutoIndexer = (AutoIndexer<Node>) mock(AutoIndexer.class);
relAutoIndexer = mock(RelationshipAutoIndexer.class);

So what could be causing the problem?

like image 923
gsingh2011 Avatar asked Oct 29 '11 06:10

gsingh2011


People also ask

What does stubbing mean in Mockito?

A stub is a fake class that comes with preprogrammed return values. It's injected into the class under test to give you absolute control over what's being tested as input. A typical stub is a database connection that allows you to mimic any scenario without having a real database.

What does the Unstubbed methods of a mock object return?

By default, for all methods that return value, mock returns null, an empty collection or appropriate primitive/primitive wrapper value (e.g: 0, false, ... for int/Integer, boolean/Boolean, ...). You can create spies of real objects.

How do you mock a method call inside another method in the same class?

We can mock runInGround(String location) method inside the PersonTest class as shown below. Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing. Then we can mock the method we want as follows.

How do I return an object in Mockito?

In Mockito, you can specify what to return when a method is called. That makes unit testing easier because you don't have to change existing classes. Mockito supports two ways to do it: when-thenReturn and doReturn-when . In most cases, when-thenReturn is used and has better readability.


1 Answers

There is no problem at all.

Let's examine these 4 lines of code:

IndexManager indexManager = mock(IndexManager.class);
when(graphDb.index()).thenReturn(indexManager);
when(indexManager.getNodeAutoIndexer()).thenReturn(nodeAutoIndexer);
when(graphDb.index().getRelationshipAutoIndexer()).thenReturn(relAutoIndexer);

The first line creates a mock indexManager.

The second one tells the mock graphDb to return indexManager (the mock created at first line) when the index method is called.

The third one telle the mock indexManager (created at first line) to return nodeAutoIndexer when its getNodeAutoIndexer method is called.

And the last line calls graphDb.index(), which returns the mock indexManager (you told it to do that at line two), and asks this indexManager (which is the mock you created at first line) to return relAutoIndexer when its getRelationshipAutoIndexer method is called.

The last line works only because you told the mock graphDb what to return when its index method is called. If you had not done this before, the mock graphDb.index() method would have returned null and you would have had an NPE.

like image 184
JB Nizet Avatar answered Oct 23 '22 12:10

JB Nizet