I started using Mockito
this week and I'm having a problem to understand @InjectMocks
field.
I have a class A that is like this:
public class A {
public B b;
public C c;
public String string;
}
when I use it at JUnit
test with Mockito
, I call it like this:
@RunWith(MockitoJUnitRunner.class)
public class Test {
@Mock
B b;
@Mock
C c;
@InjectMocks
A a;
...
}
but I want to set the string attribute! I try it like this:
Mockito.when(a.getString()).thenReturn("STRING");
however, the test throws an Exception:
org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. For example: when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because: 1. you stub either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified. 2. inside when() you don't call method on mock but on some other object. 3. the parent of the mocked class is not public. It is a limitation of the mock engine.
Can I do something else to set this field?
Can I do something else to set this field?
Yes you can annotate your field with @Spy
too as next:
@Spy
@InjectMocks
A a;
Then you will be able to do Mockito.when(a.getString()).thenReturn("STRING");
Indeed when it is annotated with @InjectMocks
only ,Mockito
doesn't mock it, it creates a normal instance of the class A
by default, such that you cannot use Mockito.when()
on it. As workaround, you can ask Mockito
to partially mock it using @Spy
.
The exception that you actually get is due to the case #2 provided in the error message:
inside when() you don't call method on mock but on some other object.
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