Я новичок в Mockito, я пытался изучить это исключение, но не нашел конкретного ответа. Это происходит в моем коде, когда я использую два макета вместе, что означает, что я передаю через конструктор макета другой макет. Вот так:
...
OperationNode child = getNode(Operation.ADD);
child.insertNode(getConstantNode(getIntegerValue(2));
...
private ConstantNode getConstantNode(NumericalValue value){
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
Mockito.when(node.toString()).thenReturn(value.toString());
return node;
}
private IntegerValue getIntegerValue(int number) {
IntegerValue integerValue = Mockito.mock(IntegerValue.class);
Mockito.when(integerValue.getValue()).thenReturn(number);
Mockito.when(integerValue.toString()).thenReturn(Integer.toString(number));
return integerValue;
}
На одном из форумов я прочитал о том, что нельзя отправлять макет через конструктор другого макета, поскольку Mockito может запутаться с вызовами макета, поэтому я попробовал следующее:
NumericalValue value = getIntegerValue(2);
child.insertNode(getConstantNode(value));
Но безрезультатно. Я удостоверяюсь, что вызываются только методы toString() и getValue(), потому что это единственные методы, которые есть у класса. Я не понимаю, что происходит.
Я также пытался использовать макеты отдельно, чтобы увидеть, сделал ли я что-то не так:
child.insertNode(new ConstantNode(getIntegerValue(2)));
Это работает отлично.
child.insertNode(getConstantNode(new IntegerValue(2)));
Это тоже хорошо работает.
Ответ 1 · рейтинг 31 · Chayemor
Из того, что я прочитал в "Выпуске 53" mockito (https://code.google.com/p/mockito/issues/detail?id=53), в моем коде возникла проблема из-за используемой в Mockito среды проверки. Именно следующий код вызывал исключение как таковое.
private ConstantNode getConstantNode(NumericalValue value){
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
Mockito.when(node.toString()).thenReturn(value.toString());
return node;
}
Если вы помните из моего кода, значение параметра ТАКЖЕ МАКЕТ, поэтому, когда value.toString() вызывается на thenReturn(), я считаю (и кто-нибудь, пожалуйста, поправьте меня, если я ошибаюсь), что среда проверки запускается и гарантирует, что каждый " когда" был thenReturn() вызван/проверен/и т.д. Так что, если это произойдет, Mockito.when(node.toString()).thenReturn(value.toString() не будет проверен, потому что он не вернулся из valute.toString(), с которого началась вся цепочка "проверить все".
Как я это исправил:
private ConstantNode getConstantNode(NumericalValue value){
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
String numberToString = value.toString();
Mockito.when(node.toString()).thenReturn(numberToString);
return node;
}
Таким образом, его может проверить. Я нахожу это полным запахом кода, потому что мне буквально придется оставить комментарий, объясняющий, почему я использую в коде, казалось бы, бесполезную промежуточную переменную.
Спасибо за помощь.
Ответ 2 · рейтинг 8 · Jeff Bowman
В этом вопросе уже опубликовано несколько хороших исправлений, но для тех, у кого все еще есть проблемы с его пониманием, подумайте о порядке, в котором Java вызывает все эти методы. Согласно Спецификации языка Java, Java оценивает каждый параметр метода слева направо перед вызов метода:
integerValue.getValue(), который записывает Mockito
when, где Mockito берет последний звонок (к integer.getValue) и начинает настройку заглушки
value.toString, который является насмешливым звонком, который записывает Mockito
thenReturn на стаббере
Mockito жалуется именно потому, что вызов макета, шаг 3, происходит после шага 2 (when), но до шага 4 (thenReturn), в результате чего платформа проверки жалуется на затыкать. Джой, ваш ответ перемещает неприятный шаг 3 до шага 1, и это нормально; Саджан полностью удаляет его из утверждения, что тоже нормально.
Ответ 3 · рейтинг 2 · Sajan Chandran
думаю проблема в линии
Mockito.when(node.toString()).thenReturn(value.toString()); в методе getConstantNode
Попробуйте удалить строку и проверьте, работает ли она. Может быть, вы можете сделать что-то вроде
int num = 2;
child.insertNode(getConstantNode(getIntegerValue(num), num);
...
private ConstantNode getConstantNode(NumericalValue value){
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
Mockito.when(node.toString()).thenReturn(Integer.toString(number));
return node;
}
private IntegerValue getIntegerValue(int number) {
IntegerValue integerValue = Mockito.mock(IntegerValue.class);
Mockito.when(integerValue.getValue()).thenReturn(number);
return integerValue;
}
Ответ 4 · StuPointerException
Я думаю, что это проблема с порядком вызовов и проверкой Mockito Framework. Попробуйте это и посмотрите, поможет ли это:
...
OperationNode child = getNode(Operation.ADD);
IntegerValue value = getIntegerValue(2);
ConstantNode node = Mockito.mock(ConstantNode.class);
Mockito.when(node.evaluate()).thenReturn(value);
Mockito.when(node.toString()).thenReturn(value.toString());
child.insertNode(node);
...
private IntegerValue getIntegerValue(int number) {
IntegerValue integerValue = Mockito.mock(IntegerValue.class);
Mockito.when(integerValue.getValue()).thenReturn(number);
Mockito.when(integerValue.toString()).thenReturn(Integer.toString(number));
return integerValue;
}
Источник: https://code.google.com/p/mockito/issues/detail?id=53