Модульное тестирование объектов модели предметной области - PullRequest
6 голосов
/ 02 марта 2010

В нашей модели модели домена Core у нас есть класс с именем "Category", конструктор которого является внутренним по дизайну. Поскольку конструктор является внутренним, при написании тестовых примеров я не смогу создать объект категории.

Итак, мой вопрос, лучше ли делать публичный конструктор только для того, чтобы сделать класс "Category" тестируемым? Или я не должен проверять эту «категорию», вместо этого я должен был проверить класс / метод, ответственный за создание этого объекта?

Та,

Rajeesh

Ответы [ 4 ]

6 голосов
/ 02 марта 2010

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

В .NET есть InternalsVisibleToAttribute , который позволяет вам подвергать внутренних членов юнит-тестам.

5 голосов
/ 02 марта 2010

TDD означает Test- Driven Design, и можно сделать вывод, что конструктор не может быть внутренним «по замыслу», если вы не можете его проверить.

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

Зачастую конструкторы делаются внутренними для защиты инвариантов, но вы также можете достичь той же цели с открытым конструктором, который принимает требуемый ввод в качестве параметров конструктора.

public class MyClass
{
    private readonly string requiredString;

    public MyClass(string requiredString)
    {
        if (requiredString == null)
        {
            throw new ArgumentNullException("requiredString");
        }
        this.requiredString = requiredString;
    }
}

Обратите внимание, как комбинация пункта Guard и ключевого слова readonly защищает инвариант класса. Часто это хорошая альтернатива внутренним конструкторам.

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

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

3 голосов
/ 02 марта 2010

Добавить

 [assembly: InternalsVisibleTo("UnitTestAssembly")]

в ваш AssemblyInfo.cs. Тогда UnitTestAssembl.dll сможет вызывать ваши внутренние методы. Более подробная информация доступна здесь .

0 голосов
/ 02 марта 2010

Можно подумать о создании статического фабричного метода с именем

Category *ConstructCategory_ForUnitTest();

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

Из названия видно, что его нельзя использовать вне контекста тестирования, и проверка кода может легко обнаружить «незаконное» использование в коде производственного класса.

...