Вопрос

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

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

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

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

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

Это было полезно?

Решение

То, что вы описываете, государственная проверка где вы утверждаете в состоянии объекта домена. Есть ветвь TDD, которая называется Проверка поведения Это использует фиктивные объекты.

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

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

Другие советы

Хорошо, этот ответ слишком поздно на год ;-)

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

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

Вместо того, чтобы тестировать, если Custom.Name равен "FOO", вы предпочитаете проверить, есть ли ожидающее событие CustomErrename со значением "FOO" в вашем магазине событий. (В вашем списке событий UOW или в вашей организации в зависимости от реализации)

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

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

Делайте то, что работает лучше всего для вас.

Пара вещей.

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

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

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

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

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

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

Существует количество насмешливых структур, которые автоматизируют создание макета, путем динамического генерирования классов, которые реализуют заданный интерфейс. Наиболее популярными являются Rhino.mocks и MOQ.

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

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

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

  1. Использование макетов и тестов для разработки объектов, основанных на роле
  2. Фиктивные роли, а не объекты
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top