Моделирование и тестирование классов с несколькими параметрами конструктора - PullRequest
3 голосов
/ 21 февраля 2011

Мои классы уровня обслуживания настроены для внедрения в конструктор.Когда я проверяю и проверяю эти классы, как мне избежать необходимости передавать null для параметров, которые я не буду использовать в своем тесте?

Пример кода, который я стараюсь избегать:

[TestFixture]
public class SomeServicesTests
{
    SomeServices _someServices;

    [SetUp]
    public void Initialize()
    {
        _someServices= new SomeServices (null, 
                                        new StubRepositoryOne(), 
                                        null, 
                                        null, 
                                        new StubRepositoryTwo(), 
                                        null, 
                                        null, 
                                        null,
                                        null);

    }

    [Test]
    public void Test_Something()
    {
        string input = "yes";
        string exptectedOutput = "no";

        string output = _someServices.SomeFunction(input); // uses StubRepositoryOne and StubRepositoryTwo
        Assert.AreEqual(exptectedOutput, output);
    }
}

Ответы [ 3 ]

3 голосов
/ 25 февраля 2011

Добавляю мой ответ после того, как он уже принят, но ...

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

С другой стороны, если то, что вы делаете здесь, представляет собой ручной указатель службы и вы тестируете только подмножество функций, возможно, вы захотите создать конструкторы только для тестирования. Такие как:

internal SomeServices(IServiceOne one, IServiceTwo two)
{
}

Или предоставьте сервисы с помощью методов получения / установки и назначьте их соответствующим образом. Опять же, внутреннее ключевое слово здесь может быть использовано для поддержания чистоты вашего дизайна:

public IServiceOne One
{
   get { return _one; }
   internal set { _one = value; }
}

Конечно, вы захотите добавить атрибут InternalsVisibleTo в свой код, чтобы ваши тесты могли получить доступ к этим внутренним методам.

2 голосов
/ 21 февраля 2011

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

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

2 голосов
/ 21 февраля 2011

Я обычно проверяю введенные параметры против нуля. Обычно я просто передаю

new Mock<T>().Object

для них.

...