Reputation: 751
I have interface
Interface MyInterface {
myMethodToBeVerified (String, String);
}
And implementation of interface is
class MyClassToBeTested implements MyInterface {
myMethodToBeVerified(String, String) {
…….
}
}
I have another class
class MyClass {
MyInterface myObj = new MyClassToBeTested();
public void abc(){
myObj.myMethodToBeVerified (new String(“a”), new String(“b”));
}
}
I am trying to write JUnit for MyClass. I have done
class MyClassTest {
MyClass myClass = new MyClass();
@Mock
MyInterface myInterface;
testAbc(){
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String(“a”), new String(“b”));
}
}
But I am getting mockito wanted but not invoked, Actually there were zero interactions with this mock at verify call.
can anyone suggest some solutions.
Upvotes: 75
Views: 307364
Reputation: 7937
@Jk1's answer is fine, but Mockito also allows for more succinct injection using annotations:
@InjectMocks MyClass myClass; //@InjectMocks automatically instantiates too
@Mock MyInterface myInterface
But regardless of which method you use, the annotations are not being processed (not even your @Mock) unless you somehow call the static MockitoAnnotations.openMocks(context)
or annotate the class with @RunWith(MockitoJUnitRunner.class)
.
Upvotes: 8
Reputation: 1
This is because of your class was not invoked correctly. For example,
@Mock ClassName className;
.....verify(className).method(argument1, argument2); //Actual code
In this case, className.class
was not invoked for the junit
.
Make it to the following:
@Mock
Class className;
.....
ClassName className = mock(ClassName.class);
verify(className).method(argument1, argument2);
Upvotes: 0
Reputation: 7679
This exception can also be thrown if say, you expect thisMethod() to execute, but it didn't. It didn't because it's inside a condition that was not met.
For example, if you have some unit test that says verify thisMethod() is executed, but in fact, it was not because varX and varY are not equal.
//method expected to be called.
if( varX == varY){
thisMethod();
}
//test
Mockito.verify(foo).thisMethod();
Upvotes: 0
Reputation: 11443
You need to inject mock inside the class you're testing. At the moment you're interacting with the real object, not with the mock one. You can fix the code in a following way:
void testAbc(){
myClass.myObj = myInteface;
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}
although it would be a wiser choice to extract all initialization code into @Before
@Before
void setUp(){
myClass = new myClass();
myClass.myObj = myInteface;
}
@Test
void testAbc(){
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}
Upvotes: 32
Reputation: 834
@jk1 answer is perfect, since @igor Ganapolsky asked, why can't we use Mockito.mock here? i post this answer.
For that we have provide one setter method for myobj and set the myobj value with mocked object.
class MyClass {
MyInterface myObj;
public void abc() {
myObj.myMethodToBeVerified (new String("a"), new String("b"));
}
public void setMyObj(MyInterface obj)
{
this.myObj=obj;
}
}
In our Test class, we have to write below code
class MyClassTest {
MyClass myClass = new MyClass();
@Mock
MyInterface myInterface;
@test
testAbc() {
myclass.setMyObj(myInterface); //it is good to have in @before method
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}
}
Upvotes: 3
Reputation: 79838
Your class MyClass
creates a new MyClassToBeTested
, instead of using your mock. My article on the Mockito wiki describes two ways of dealing with this.
Upvotes: 10