Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking ColumnDefinitions.Definition does return mock, but is behaves like null in the tested code

I have following code preparing mocks to test my service using Cassandra (I need to mock com.datastax.driver.core.ColumnDefinitions.Definition) :

@RunWith(PowerMockRunner.class)
public class TestMyClass{
private MyClass target;
  @Before
  public void setUp() throws Exception {
    ColumnDefinitions mockColumnDefinitions=Mockito.mock(ColumnDefinitions.class);
    Mockito.when(mockRow.getColumnDefinitions()).thenReturn(mockColumnDefinitions);
    target= new MyClass();
    Definition mockDef = Mockito.mock(Definition.class);
    List<Definition> defList = new ArrayList<Definition>();
    defList.add(mockDef);
    Iterator mockIterator = Mockito.mock(Iterator.class);
    Mockito.when(mockColumnDefinitions.iterator()).thenReturn(mockIterator);
    Mockito.when(mockIterator.hasNext()).thenReturn(true, false);
    Mockito.when(mockIterator.next()).thenReturn(mockDef);
    Mockito.when(mockDef.getName()).thenReturn(NAME);
  }
 @Test
 public void testMyMethod() throws Exception {
    target.MyMethod();
 }
}

Test execution goes fine this place, and I have this type of code in different places, so it should work. Inside the service I am testing I have following code:

ColumnDefinitions colDef = row.getColumnDefinitions();
Iterator<Definition> defIterator = colDef.iterator();
while (defIterator.hasNext()) {
    Definition def = defIterator.next();
    String columnName = def.getName();
}

When I debug this code, I see, that both colDef and defIterator are mocked successfully. I see something like that in debug variables area:

Mock for Iterator, hashCode: 430126690

But after defIterator.next() invocation I see that though def is an object and not null, it doesn't show hashcode like for Iterator, instead I see this:

com.sun.jdi.InvocationException occurred invoking method.

And after invoking this string:

String columnName = def.getName();

I immediately get NullPointerException like if def is null. What am I doing wrong? Thanks.

EDIT 1 ________________________________________________________________________

I also tried to use PowerMockito with the same methods instead, the result is the same.

EDIT 2 ________________________________________________________________________

I added the whole test method code.

like image 625
Battle_Slug Avatar asked Oct 19 '25 00:10

Battle_Slug


1 Answers

It is been a while since this question was created. I have faced this same problem few days ago and I have solved it in the following manner (I hope my proposed solution helps someone in the future):

First of all, I want to clarify that ColumnDefinition.Definition class is a public static nested class that has four private final fields and only has one constructor: Definition (String keyspace, String table, String name and DataType type) (for more details please refer to the ColumnDefinitions.Definition javadoc and ColumnDefinitions source code). Therefore this nested class could not be mocked by Mockito nor Powermock because of its final fields.

SOLUTION:

I had to create a real object, not a mocked one of the class ColumnDefinition.Definition using reflection, so you can initialise the mockDef object as follows:

Constructor<Definition> constructor = (Constructor<Definition>) Definition.class.getDeclaredConstructors()[0]; // as Definition only has one constructor, 0 will be passed as index
constructor.setAccessible(true);
Definition mockDef = constructor.newInstance("keyspace", "table", "name", null);

replacing this line of code in your snippet:

Definition mockDef = Mockito.mock(Definition.class);

Then the NullPointerException will never be thrown again when executing this line of code:

String columnName = def.getName();
like image 167
jcflorezr Avatar answered Oct 21 '25 12:10

jcflorezr