Есть ли способ сделать свойство PHP доступным только для чтения для объекта? У меня есть объект с парой массивов. Я хочу получить к ним доступ, как обычно к массиву
echo $objObject->arrArray[0];
Но я не хочу иметь возможность записи в эти массивы после их создания. Это похоже на PITA для создания локальной переменной:
$arrArray = $objObject->getArray1();
echo $arrArray[0];
И в любом случае, хотя он сохраняет массив в первозданном виде, это не мешает мне переписать локальную переменную массива. Я не могу изобразить ...
Прочитав интересную статью о поведении модульного тестирования вместо состояния, я понял, что мои модульные тесты часто тесно связаны с моим кодом, потому что я использую имитации. Я не могу писать модульные тесты для изображения без макетов, но факт заключается в том, что эти макеты очень сильно связывают мой модульный тест с моим кодом из-за вызовов ожидающих и возврата.
Например, когда я создаю тест, который использует макет, я записываю все вызывает конкретный макет и присваивает возвращаемые значения. Теперь, когда я по какой-то причине меняю реализацию реального кода, многие тесты не выполняются, потому что макет не ожидал этого вызова, что заставило меня обновить и модульный тест, и фактически заставило меня реализовать каждое изменение дважды ... Это часто случается.
Является ли эта проблема присущей использованию насмешек, и должен ли я научиться жить с этим, или я делаю что-то в корне неправильно? Пожалуйста, просветите меня :) Конечно, приветствуются ясные примеры, сопровождающие объяснение.
когда я создаю тест, который использует макет, Я записываю все звонки на конкретный смоделируйте и присвойте возвращаемые значения
Похоже, вы завышаете ожидания.
Старайтесь встраивать в свои тесты как можно меньше установочного кода: заглушайте (а не ожидайте) все поведение, не относящееся к текущему тесту, и указывайте только возвращаемые значения, которые абсолютно необходимы для того, чтобы ваш тест работал.
Этот ответ включает краткий пример (а также альтернативное, более подробное объяснение).
По моему опыту, макеты используются только на границах (под)систем. Если у меня есть два класса, которые сильно связаны, я не издеваюсь над ними, а тестирую их вместе. Примером может быть композит и посетитель. Если я тестирую конкретного посетителя, я не использую макет для композита, а создаю настоящие композиты. Можно возразить, что это не модульный тест (зависит от определения того, что такое модуль). Но это не имеет большого значения. Чего я пытаюсь добиться, так это:
Только если я сталкиваюсь с границей подсистемы, я использую макеты. Пример: у меня есть композит, который может рендерить себя в рендерере. Я бы имитировал рендерер, если я тестирую логику рендеринга композита.
Тестирование поведения вместо состояния поначалу выглядит многообещающе, но в целом я бы тестировал состояние, так как полученные в результате тесты легче поддерживать. Моки — это пушка. Не колите орех кувалдой.
Здесь уже есть несколько хороших ответов, но для меня хорошим практическим правилом является проверка требований метода, а не реализации. Иногда это может означать использование фиктивного объекта, потому что взаимодействие является требованием, но обычно лучше протестировать возвращаемое значение метода или изменение состояния объекта.