TDD, DDD и инкапсуляция - PullRequest
       47

TDD, DDD и инкапсуляция

23 голосов
/ 18 июля 2009

После нескольких лет следования за плохой практикой, вынесенной «архитекторами» на моем рабочем месте и думая, что должен быть лучший способ, я недавно начал изучать TDD и DDD и думаю, что принципы и практики было бы отлично подходит для сложности программного обеспечения, которое мы пишем.

Однако многие из примеров TDD, которые я видел, вызывают метод для объекта предметной области, а затем проверяют свойства объекта, чтобы убедиться, что поведение выполняется правильно.

С другой стороны, несколько уважаемых людей в отрасли (Грег Янг особенно заметно в своих выступлениях по CQRS) выступают за полную инкапсуляцию каждого предметного объекта путем удаления всех «получателей».

Поэтому мой вопрос таков: как проверить работоспособность объекта домена, если ему запрещено получать его состояние?

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

Ответы [ 8 ]

17 голосов
/ 18 июля 2009

То, что вы описываете, это проверка состояния , в которой вы утверждаете состояние объекта домена. Существует ветвь TDD, которая называется проверка поведения , которая использует фиктивные объекты.

Проверка поведения позволяет указать, какие методы следует вызывать и, если хотите, какие методы не вызывать.

Загляните в эту статью Мартина Фаулера для получения более подробной информации: Насмешки - это не заглушки .

9 голосов
/ 05 мая 2010

ОК, этот ответ опоздал на год; -)

Но когда вы хотите протестировать модели CQRS, вы можете делать утверждения о событиях запущенного домена вместо утверждений о состоянии объекта.

например. если вы хотите проверить, если вызов: customer.Rename ("Foo") приводит к правильному поведению.

Вместо проверки, если customer.Name равняется «foo», вам лучше проверить, есть ли ожидающее событие CustomerRename со значением «Foo» в вашем хранилище ожидающих событий. (в вашем uow или в вашем списке событий сущности в зависимости от реализации)

4 голосов
/ 18 июля 2009

Если вы действительно собираетесь пойти так далеко, чтобы запретить получение состояния, то вы будете ограничены поведенческим тестированием, возможно, с помощью фальшивой среды, такой как TypeMock, которая может отслеживать поведение вашего объекта. Если вы умеете делать чисто BDD, то теоретически вы можете утверждать правильность всей вашей системы просто по тому, как она себя ведет.

На практике я обнаружил, что BDD во многих случаях более хрупкий, чем просто тестирование с учетом состояния. Хотя некоторые люди могут призывать к определенной теории, она работает, только если она работает для вас. Государственное тестирование по-прежнему составляет 90% всех написанных нами модульных тестов, и мы хорошо знаем о BDD в нашей команде.

Делай то, что лучше для тебя.

2 голосов
/ 23 февраля 2010

Привет, Джастин, как и ты, я недавно думал о добавлении геттеров в мой объект домена только для записи для модульного тестирования, но теперь я убежден, что был неправ. Предполагая, что вы изначально приняли идею домена только для записи, то, если у вас есть геттеры, вы напрашиваетесь на неприятности. Принцип домена только для записи требует, чтобы вы запускали событие из вашего доменного объекта или читали из проекции, которую написал ваш доменный объект, или что-то в этом роде. Как только вы выставляете геттеры, вы начинаете выставлять «форму» объекта, и, как говорит Грег Янг, «доменные объекты имеют поведение, а не форму».

При этом я борюсь с тем же вопросом ... как вы тестируете доменный объект только для записи? Вот мой текущий план: я подумываю сделать так, чтобы мой объект домена запускал событие домена, говоря «Эти свойства изменены», и в моем модульном тесте я зарегистрируюсь для этого перед отправкой «EditCommand». Ознакомьтесь с постом Уди Даана о событиях домена здесь , а также посмотрите , что говорит Эрик Эванс о событиях домена .

2 голосов
/ 18 июля 2009

То, что вы упоминаете, называется государственным тестированием. Там также тестирование поведения. Для этого используются методы внедрения зависимостей, инверсии управления и насмешек:

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

Существует множество Mocking Frameworks, которые автоматизируют создание фиктивных объектов, динамически генерируя классы, которые реализуют данный интерфейс. Наиболее популярными являются Rhino.Mocks и Moq.

2 голосов
/ 18 июля 2009

Я вызываю общедоступные методы ввода системы (т. Е. Помещаю входные данные в систему), а затем получаю (и утверждаю) вывод системы. Я проверяю не внутреннее состояние системы, а ее публичное / видимое поведение: Следует ли проверять внутреннюю реализацию или только публичное поведение?

2 голосов
/ 18 июля 2009

Пара вещей.

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

Во-вторых, архитектура ОО oldschool пытается сделать программное обеспечение безопасным, используя языковые средства защиты, чтобы предотвратить доступ к объектам. Архитектура TDD делает программное обеспечение более устойчивым благодаря написанию тестов, которые проверяют, что на самом деле делает код, уделяя меньше внимания использованию языковых конструкций, чтобы гарантировать, что программа не делает.

Наконец, проверка свойства - не единственный способ проверить код, выполнив то, что он должен был сделать. Книга xUnit Design Patterns описывает другие подходы здесь: http://xunitpatterns.com/Result%20Verification%20Patterns.html

1 голос
/ 27 апреля 2010

Мне было интересно то же самое, пока я наконец не наткнулся на следующие документы. Я обнаружил, что они являются отличными учебниками по проверке поведения, особенно первый, который дал мне несколько «ага моментов»:

  1. Использование макетов и тестов для проектирования объектов на основе ролей
  2. Ложные роли, а не объекты
...