свойства только для чтения в PHP?

Есть ли способ сделать свойство PHP доступным только для чтения для объекта? У меня есть объект с парой массивов. Я хочу получить к ним доступ, как обычно к массиву

echo $objObject->arrArray[0];

Но я не хочу иметь возможность записи в эти массивы после их создания. Это похоже на PITA для создания локальной переменной:

$arrArray = $objObject->getArray1();
echo $arrArray[0];

И в любом случае, хотя он сохраняет массив в первозданном виде, это не мешает мне переписать локальную переменную массива. Я не могу изобразить ...

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

Например, когда я создаю тест, который использует макет, я записываю все вызывает конкретный макет и присваивает возвращаемые значения. Теперь, когда я по какой-то причине меняю реализацию реального кода, многие тесты не выполняются, потому что макет не ожидал этого вызова, что заставило меня обновить и модульный тест, и фактически заставило меня реализовать каждое изменение дважды ... Это часто случается.

Является ли эта проблема присущей использованию насмешек, и должен ли я научиться жить с этим, или я делаю что-то в корне неправильно? Пожалуйста, просветите меня :) Конечно, приветствуются ясные примеры, сопровождающие объяснение.

12
задан nkr1pt 30 August 2010 в 13:28
поделиться

3 ответа

когда я создаю тест, который использует макет, Я записываю все звонки на конкретный смоделируйте и присвойте возвращаемые значения

Похоже, вы завышаете ожидания.

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

Этот ответ включает краткий пример (а также альтернативное, более подробное объяснение).

5
ответ дан 2 December 2019 в 21:42
поделиться

По моему опыту, макеты используются только на границах (под)систем. Если у меня есть два класса, которые сильно связаны, я не издеваюсь над ними, а тестирую их вместе. Примером может быть композит и посетитель. Если я тестирую конкретного посетителя, я не использую макет для композита, а создаю настоящие композиты. Можно возразить, что это не модульный тест (зависит от определения того, что такое модуль). Но это не имеет большого значения. Чего я пытаюсь добиться, так это:

  1. Писать читаемые тесты (тесты без макетов в большинстве случаев легче читать).
  2. Тестируйте только конкретную область кода (в примере конкретный посетитель и соответствующую часть композита).
  3. Пишите быстрые тесты (пока я создаю экземпляры только нескольких классов, в примере с конкретными композитами, это не проблема... следите за транзитивными созданиями).

Только если я сталкиваюсь с границей подсистемы, я использую макеты. Пример: у меня есть композит, который может рендерить себя в рендерере. Я бы имитировал рендерер, если я тестирую логику рендеринга композита.

Тестирование поведения вместо состояния поначалу выглядит многообещающе, но в целом я бы тестировал состояние, так как полученные в результате тесты легче поддерживать. Моки — это пушка. Не колите орех кувалдой.

4
ответ дан 2 December 2019 в 21:42
поделиться

Здесь уже есть несколько хороших ответов, но для меня хорошим практическим правилом является проверка требований метода, а не реализации. Иногда это может означать использование фиктивного объекта, потому что взаимодействие является требованием, но обычно лучше протестировать возвращаемое значение метода или изменение состояния объекта.

0
ответ дан 2 December 2019 в 21:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: