2013-09-28 2 views
1

Я новичок в тестировании PHP и пытаюсь создать простой проект с TDD.TDD, Рефакторинг после перемещения функций класса для абстракции

Простая идея состояла в том, чтобы сделать простую картографическую установку.

Я начал сочинительствы тесты и быстро начал мять вверх CardDeck класса и CardStack класса от моего failling тестов. Оба они реализовали одни и те же методы, такие как getTop(), getTopStack() .. поэтому я решил реализовать CardDeckInterface, абстрактный класс BaseCardStack, чтобы высушить его.

После рефакторинга. CardDeck и CardStack расширяет BaseCardStack, который реализует CardStackInterface.

Различия CardDeck и CardStack - это конструкция и несколько дополнительных функций для CardStack. Кроме того, ни одна из реализованных функций из BaseCardStack не перезаписывается.

Вот где мои проблемы. В моем CardDeckTest у меня были тесты, связанные с реализованными методами, которые должны были перемещать BaseCardDeck.

Должен ли я держать свои текущие тесты в своем CardDeckTest (они все еще проходят по-прежнему) и написать дополнительный набор тестов для CardStackTest? Это похоже на неправильное решение, поскольку методы уже протестированы и ничем не отличаются (не перезаписываются), как я уже упоминал, реализованные методы из BaseCardStack не перезаписываются.

Вместо этого я думаю, что я должен переместить/написать тесты для моего абстрактного класса.

В основном я хочу проверить функции в своем абстрактном классе, которые, как я знаю, будут реализованы без перезаписи.

Но как это сделать? Должен ли я высмеивать? Должен ли я менять свои шаблоны?

ответ

1

Вместо я думаю, что я должен двигаться тесты/записи для моего абстрактного класса

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

Но прежде чем вы сделаете несколько предупреждений: подумайте дважды. Вам, вероятно, не нужен абстрактный класс. Похоже, что у вас есть какая-то структура данных, которая хорошо подходит для задания, которое используется двумя классами, однако эти два класса не являются такой структурой данных.

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

Любимый composition over inheritance.

Просто скажите, что для вашего первоначального вопроса о том, как протестировать абстрактный класс, вы создаете тестовый двойной из него. Это либо работает с PHPUnit mocks, который способен mock abstract classesTesting Abstract Classes), и при этом принимает на себя определенные методы.

Но я обычно создаю класс-заглушку для тестирования, который создает новый файл, который содержит определение класса, простирающееся от абстрактного базового класса, который в остальном независим от остальной части приложения (но привязан к абстрактному классу) а затем использовать его как субъект в единичном тесте (сравните с Test methods of Abstract Class with PHPUnit).

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

Надеюсь, что это поможет, не стесняйтесь спрашивать об этом.

О, и на самом деле это еще один совет. То, что я делал один или два раза для абстрактного базового класса, - это также создать тестовый файл abtract, который содержит тесты для базы. Продвинувшись от него, то для конкретных тестов внедрения работа была очень неплохой. IIRC связанный с ним вопрос был:

+0

благодаря ответ имеет смысл. Но вы пишете -> «На самом деле это и вы, возможно, захотите применить один и тот же набор модульных тестов для любого другого класса, реализующего этот интерфейс», поэтому, если базовая абстракция получила getTop(), она распространяется на класс колоды и стека, вы хотите, чтобы я правильно тестировал их, даже если они идентичны тем, что были в базовом тесте? –

+1

Что я имел в виду, так это то, что если у вас есть интерфейс, вы можете написать один phpunit-testcase для этого интерфейса, а затем протестировать каждый конкретный класс, реализующий этот интерфейс с этим тестовым кодом. Это не зависит от наличия абстрактного базового класса. Это более ясно? – hakre

+0

Да это ясно :) Я собираюсь пойти на Google Writting тестирование на интерфейс. –

Смежные вопросы