Объекты Модели предметной области поблочного тестирования

В нашем Базовом дизайне модели предметной области у нас есть класс под названием "Категория", конструктор которой является внутренним дизайном. Так как конструктор является внутренним при записи случаев модульного теста, я не смогу создать объект "Категории".

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

Ta,

Rajeesh

6
задан lexeme 23 April 2012 в 12:53
поделиться

4 ответа

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 Clause и ключевого слова readonly защищает инвариант класса. Это часто является хорошей альтернативой внутренним конструкторам.

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

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

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

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

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

6
ответ дан 8 December 2019 в 17:21
поделиться

Добавьте

 [assembly: InternalsVisibleTo("UnitTestAssembly")]

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

3
ответ дан 8 December 2019 в 17:21
поделиться

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

Category *ConstructCategory_ForUnitTest();

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

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

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

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