Должен ли объект с использованием аннотации @Mock иметь подробное значение? - PullRequest
0 голосов
/ 07 декабря 2018

Я новичок в Мокито и у меня есть вопрос.Допустим, я пытаюсь использовать экземпляр объекта в моем методе тестирования.Я знаю, что могу использовать @Mock для этого, потому что мы пытаемся изолировать тестирование от методов этого объекта.Однако для управления веткой тестирования мне нужно установить некоторые значения в этом объекте.Должен ли я использовать Mock или просто использовать новый Object() способ его создания?Или это не имеет значения (все в порядке)?

Спасибо.

1 Ответ

0 голосов
/ 07 декабря 2018

Давайте выясним, ладно?!

import org.mockito.Mockito;

class Scratch {  
    public final static String STATIC_CONST = "static const";
    private final String JUST_CONST = "private const";
    protected String protectedField = "protected field";
    String packageProtectedField = null;

    public static void main(String[] args) {
        Scratch mocked = Mockito.mock(Scratch.class);
        System.out.println("static    = " + mocked.STATIC_CONST);
        System.out.println("const     = " + mocked.JUST_CONST);
        System.out.println("protected = " + mocked.protectedField);
        System.out.println("package   = " + mocked.packageProtectedField);

        mocked.packageProtectedField = "but now";
        System.out.println("updated  = " + mocked.packageProtectedField);
    }
}

Вышеуказанные отпечатки:

static = static const

const = private const

protected = null

package = null

updated =, но сейчас

Некоторые мысли:

Очевидно, static constна самом деле то, что вы ожидаете (я использовал mocked.STATIC_CONST, чтобы получить значение, но, эй, оно статическое, поэтому значение берется не из mocked, а из определения класса Scratch в любом случае).

AНемного удивительно, по крайней мере для меня то, что назначение полей для макета объекта действительно работает.Но обратите внимание: назначения в исходном классе действительны только для этого поля final.Другими словами: Mockito делает это правильно, но не для не финальных полей.

Еще более удивительно, что в макет можно хранить значения ...

Но, честно говоря, ничего из этого не имеет значения.Видите ли, в звуковом дизайне все ваши изменяемые поля должны быть private в самом первом месте.Это изменчивое состояние представляет собой абсолютное ядро ​​ваших объектов. Нет внешний код должен когда-либо иметь дело с ними!Другими словами: в идеале, даже ваши тесты не заботятся о внутреннем состоянии ваших объектов (в очень редких ситуациях может иметь смысл иметь защищенный от пакетов метод getter для доступа к внутреннему состоянию для простоты проверки, но это должно бытьредкое исключение).

Кроме того: когда вы издеваетесь над объектом, вы абсолютно никоим образом не должны иметь дело с полями этой насмешки.Вы видите: все методы на этом макете ... они не имеют ничего общего с исходным исходным кодом в вашем классе.Это всего лишь пустые оболочки, которые вы можете настроить / проверить с помощью соответствующих методов Mockito.Пусть это впитывается: фактическое содержание полей в макетируемом объекте не может иметь значения: потому что методы, которые обычно имеют дело с этими полями ... "не существует"!

Итак, короткая история:как показано, макетированные объекты могут нести состояние.Но, как объяснено: вы должны полностью игнорировать этот аспект.Единственный правильный способ использовать макеты - это указывать / проверять вызовы методов для них.

Наконец: я ожидаю, что EasyMock, PowerMock (ito) ведут себя аналогичным образом.С другой стороны, я бы тоже не удивился, когда другие насмешливые фреймворки на самом деле ведут себя немного иначе.Я тестировал только с Mockito, потому что, imho, в 2018 году, Mockito - это единственная среда разработки, которую следует использовать при написании модульных тестов для JVM.

...