Исключение: mockito хотел, но не был вызван, на самом деле было нулевое взаимодействие с этим макетом
У меня есть интерфейс
Interface MyInterface {
myMethodToBeVerified (String, String);
}
И реализация интерфейса
class MyClassToBeTested implements MyInterface {
myMethodToBeVerified(String, String) {
…….
}
}
У меня есть еще один класс
class MyClass {
MyInterface myObj = new MyClassToBeTested();
public void abc(){
myObj.myMethodToBeVerified (new String("a"), new String("b"));
}
}
Я пытаюсь написать JUnit для MyClass. Я сделал
class MyClassTest {
MyClass myClass = new MyClass();
@Mock
MyInterface myInterface;
testAbc(){
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}
}
Но я получаю mockito, но не вызывается, на самом деле было нулевое взаимодействие с этим макетом при проверке вызова.
может кто-нибудь предложить некоторые решения.
Ответы
Ответ 1
Вам нужно добавить макет внутри тестируемого вами класса. В настоящий момент вы взаимодействуете с реальным объектом, а не с макетным. Вы можете исправить код следующим образом:
void testAbc(){
myClass.myObj = myInteface;
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}
хотя было бы разумнее выбрать весь код инициализации в @Before
@Before
void setUp(){
myClass = new myClass();
myClass.myObj = myInteface;
}
@Test
void testAbc(){
myClass.abc();
verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}
Ответ 2
Ваш класс MyClass
создает новый MyClassToBeTested
вместо использования вашего макета. Моя статья о вики Mockito описывает два способа борьбы с этим.
Ответ 3
@Ответ Jk1 - это хорошо, но Mockito также позволяет более сжатую инъекцию с помощью аннотаций:
@InjectMocks MyClass myClass; //@InjectMocks automatically instantiates too
@Mock MyInterface myInterface
Но независимо от того, какой метод вы используете, аннотации не обрабатываются (даже не ваш @Mock), если вы каким-то образом не вызываете статический MockitoAnnotation.initMocks()
или не комментируете класс с помощью @RunWith(MockitoJUnitRunner.class)
.
Ответ 4
@jk1 ответ прекрасен, так как @igor Ganapolsky спросил, почему мы не можем использовать Mockito.mock здесь? я пишу этот ответ.
Для этого мы предоставляем один метод setter для myobj и устанавливаем значение myobj с помощью 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;
}
}
В нашем тестовом классе мы должны написать ниже код
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"));
}
}