Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Mockito UnfinishedStubbingException

Автор вопроса: ChayemorОтветов: 4

Я новичок в 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)));

Это тоже хорошо работает.

  • известная проблема https://code.google.com/p/mockito/issues/detail?id=53 Sajan Chandran 21.03.2013
  • Активная ссылка: code.google.com/p/mockito/issues/detail. ?id=53 Duncan Jones 24.06.2014
  • Насмешки, возвращающие насмешки, обычно являются запахом кода. haventchecked 07.01.2019

javamockito

Ответы

Ответ 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 оценивает каждый параметр метода слева направо перед вызов метода:

  1. integerValue.getValue(), который записывает Mockito
  2. when, где Mockito берет последний звонок (к integer.getValue) и начинает настройку заглушки
  3. value.toString, который является насмешливым звонком, который записывает Mockito
  4. 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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы