Reputation: 2231
I have a very complicated class to write Junit test case. I decided to use PowerMockito since my class for which the test is to be run has a constructor initialization.
My main class is like this:
public class MainClass extends BaseClass{
MainClass(SomeClass class){
super(class);
}
public void methodToBeTested(){
some code here
}
..few other methods which I am not going to test.
}
Now I have the test case written like this:
@RunWith(PowerMockRunner.class)
public class TestClass{
@Mock
OtherClassUsedInMainClass mock1;
@Mock
OtherClassUsedInMainClass mock2;
@InjectMocks
MainClass mainClass;
@Before
public void setUp() throws Exception{
MockitoAnnotations.initMocks(this);
PowerMockito.whenNew(MainClass.class).withArguments(Mockito.any(SomeClass.class))
.thenReturn(mainClass);)
}
@Test
public void testMethodtobeTested(){
...I am using the other objects to mock data and test if this method works fine
mainClass.methodtobeTested();
\\This method will increment a value. I am just asserting if that value is right.
Assert.assertEquals(mainClass.checkCount(),RequiredCount)
}
}
I am getting a null pointer exception when running the Testcase since it tries to initialize the mainClass. It does not get mocked. I know I am doing something wrong. But I just don't know what it is.
Error:
org.mockito.exceptions.base.MockitoException:
Cannot instantiate @InjectMocks field named 'mainClass' of type 'class com.main.MainClass'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null
Caused by: java.lang.NullPointerException
This null pointer exception is thrown from a the constructor of the BaseClass when it tries to initialize another class.
Upvotes: 3
Views: 10603
Reputation: 16209
If you can't show us the actual code it is very hard to guess what exactly is happening. But it looks like your mock SomeClass
needs some stubbed behavior to satisfy the BaseClass constructor.
For example:
// the instance of MainClass you run your tests against
private MainClass instance;
@Mock
private SomeClass someClass;
@Mock
private SomethingElse somethingElse;
@Before
public void setUp() {
when(someClass.doSomething()).thenReturn(somethingElse);
instance = new MainClass(someClass);
}
@Test
public void test() {
// SETUP
when(somethingElse.doWeirdStuff()).thenThrow(new WeirdException());
// CALL
instance.performTapDance();
// VERIFY
assertTrue(instance.isWeird());
}
Upvotes: 0
Reputation: 6075
This question explains the difference between @Mock
and @InjectMocks
:
@Mock
creates a mock. @InjectMocks
creates an instance of the class and injects the mocks that are created with the @Mock
(or @Spy
) annotations into this instance.
MainClass
constructor expects a SomeClass
parameter but there isn't any mock for that.
Your code should be something like:
@RunWith(PowerMockRunner.class)
public class TestClass{
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
SomeClass mock1;
@InjectMocks
MainClass mainClass;
@Before
public void setUp() throws Exception{
...
Upvotes: 1
Reputation: 140299
Quoting this answer, which is quoting the @InjectMocks
documentation:
Constructor injection; the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only. Note: If arguments can not be found, then null is passed.
So, presumably, declare a field of type SomeClass
, and annotate it @Mock
.
Upvotes: 0