Мокито, когда не возвращается ожидаемый объект - PullRequest
0 голосов
/ 12 апреля 2020

Я пытаюсь вернуть ожидаемое значение из смоделированного метода.

TestClass testClass = TestClass.getInstance();
ClassToMock classToMock = Mockito.mock(ClassToMock.class);
testClass.setClassToMock(classToMock);
ExpectedObject expectedObject = new ExpectedObject("1", "2", "3");
when(classToMock.method(ArgumentMatchers.anyString(), ArgumentMatchers.anyBoolean(),
                        ArgumentMatchers.any(A.class), ArgumentMatchers.any(B.class))
                .thenReturn(expectedObject);
testClass.invokeTestMethod();

TestClass и invokeTestMethod имеют следующий вид:

public class TestClass {

  private ClassToMock classToMock;

  public void invokeTestMethod() {
     ExpectedObject expectedObj1 = classToMock.method("A", "B", null, null);
     ::
     ::
     ExpectedObject expectedObj2 = classToMock.method("X", "Y", null, null);
     ::
     ::
     ExpectedObject expectedObj3 = classToMock.method("P", "Q", null, null);
     ::
     ::
  }

  public void setClassToMock(ClassToMock ctm) {
     this.classToMock = ctm;
  }
}

Я установил экземпляр classToMock для TestClass, чтобы убедиться, что TestClass работает на экземпляре mock.

Чтобы сделать проблему более понятной, вызов метода происходит для смоделированного объекта (classToMock), но ожидаемое возвращаемое значение (ExpectedObject) не приходит.

Ответы [ 4 ]

1 голос
/ 12 апреля 2020

Проблема здесь: null не совпадает any(X.class), поэтому смоделированное значение не будет возвращено

Если в качестве аргумента передано null, то два последних сопоставления аргумента на месте:

  • ArgumentMatchers.any(A.class)
  • ArgumentMatchers.any(B.class)

не будет сопоставлено .

См. Документацию any(java.lang.Class):

Соответствует любому объекту данного типа, , исключая нули . (выделено жирным шрифтом, чтобы подчеркнуть)

Это потому, что с Mockito 2.1.0 внутренне пытаются оценить тип (класс) аргумента. И null - это пустая ссылка, не указывающая на экземпляр объекта. Нет ссылки на объект, класс этого объекта не может быть оценен:

null instanceOf A // will evaluate to `false`
null instanceOf B // will evaluate to `false`

См. Требуется ли нулевая проверка перед вызовом instanceof?

Решение: использовать any() или isNull() для сопоставления null

Для вызова макетированных методов , вызываемых внутри, используйте сопоставление аргументов, которое будет соответствовать null переданным значениям.

0 голосов
/ 12 апреля 2020

вам нужно передать ClassToMock ro TestClass, например, в конструктор в методе set. Таким образом, в тесте вы можете передать макет тестовому классу, и в методе invokeTestMethod макет будет использован. В данный момент вы этого не делаете, поэтому method вызывается для реального объекта

0 голосов
/ 12 апреля 2020

Спасибо всем, кто решил помочь. Я нашел исправление. В TestClass был такой вызов: ExpectedObject expectedObj1 = classToMock.method("A", "B", null, null); Два пустых параметра вызвали проблему. Итак, я перегрузил method внутри ClassToMock параметрами NON NULL. После этого изменения макет работает отлично.

0 голосов
/ 12 апреля 2020

В первом отрывке, когда метод вызывается с сигнатурой метода (String, bool, A, B) в качестве параметра, тогда как во втором отрывке вызывается метод с сигнатурой (String, String, Object, Object). Поэтому во втором отрывке classToMock.method («A», «B», null, null) возвращает ноль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...