Почему этот объект Mockito.mock вызывается вместо насмешки? - PullRequest
0 голосов
/ 02 мая 2019

Я проводил модульное тестирование своего класса и столкнулся с такой ситуацией: я имитирую объект с помощью Mockito и вызываю метод для этого объекта.Когда я это сделаю, я ожидаю, что реальный метод не будет вызван, и выполнение программы продолжится.Происходит то, что вызывается реальный метод, и я получил исключение NullPointerException, потому что это то, что произойдет, если я вызову метод с этим параметром.

Разве Mockito.mock не должен предотвращать такое поведение?

Документация Mockito говорит By default, for all methods that return value, mock returns null, an empty collection or appropriate primitive/primitive wrapper value (e.g: 0, false, ... for int/Integer, boolean/Boolean, ...). и этот ответ подтверждает мое ожидаемое поведение In a mock all methods are stubbed and return "smart return types". This means that calling any method on a mocked class will do nothing unless you specify behaviour.

Код:

public class BrokenTest {
    @Test
    public void shouldPassBecauseItIsMocked() throws IOException {
        Object anyObject = Mockito.mock(Object.class);
        ObjectOutputStream objectOutputStream = Mockito.mock(ObjectOutputStream.class);
        objectOutputStream.writeObject(anyObject);
    }
}

Я ожидал, что этот тест пройдёт, но я получаю исключение NullPointerException:

java.lang.NullPointerException
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1108)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at packageName.BrokenTest.shouldPassBecauseItIsMocked(BrokenTest.java:14)
    ...

(BrokenTest.java:14 это строка objectOutputStream.writeObject(anyObject); на самом деле)

PS: Я не очень стараюсьпроверить ObjectOutputStream но мой класс, который использует ObjectOutputStream.writeObject(Object object).Проблема действительно возникла, когда я сделал myObjectWithMockedObjectOutputStream.methodThatCallsWriteObject()

Ответы [ 2 ]

0 голосов
/ 05 мая 2019

JBNizet правильно ответил на вопросы комментариев.

writeObject является окончательным.Mockito (до последних версий, и если вы настроите его специально для этого) не может высмеивать окончательные методы.

0 голосов
/ 02 мая 2019

Mockito не меняет принцип работы языка.Методы вызываются в порядке их добавления в коде.Это означает, что в случае смоделированного метода, подобного этому:

when(mockObject.getSomething()).thenReturn(SOMETHING_ELSE);

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

Это подразумевает, что если getSomething() вызывает некоторые зависимости для смоделированного объекта, то последний не инициализируется и приводит к NPE.

Обходной путь для этого заключается в использовании другой формыКонфигурирование макета:

doReturn(SOMETHING_ELSE).when(mockObject ) .getSomething();

пожалуйста, обратите внимание, что закрывающая скобка when переместилась из-за метода до ..

Это позволяет Mokitoперехватить полный вызов метода, чтобы не было выброшено NPE.

...