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.
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With