При использовании Ninject для инъекции зависимостей лучше всего использовать Ninject в ваших модульных тестах или использовать насмешливую структуру

Я использую ninject для внедрения зависимостей в мою производственную среду. Я вижу два варианта, когда дело доходит до написания модульных тестов. Я могу либо создать конкретные классы и внедрить их с помощью ninject, либо я могу использовать насмешливую структуру, например, просто mock.

Мой мыслительный процесс состоит в том, чтобы просто использовать оба, и решающим фактором будет то, можно ли создать TestInterface повторно используемым способом. Таким образом, мы не тратим время на написание одного и того же метода Mocked, чтобы снова и снова возвращать пустой список.

Есть ли лучшая практика для такого рода вещей?


person Manny Williams    schedule 26.04.2015    source источник


Ответы (2)


При модульных тестах на классе нет особого смысла включать контейнер DI в «тестируемую систему» ​​(SUT).

  • в принципе модульный тест класса должен проверять класс и только класс
  • обычно вы не можете «повторно использовать» привязки в модульном тесте, вы должны создавать их для конкретного модульного теста. Поэтому вы только повторно тестируете ninject, но не то, как вы его применяете. Ninject уже протестирован. Так что никакой реальной пользы для вас.

Если вы проводите приемочное/модульное тестирование на уровне компонентов или приложений, то имеет смысл включить Ninject в SUT.

Для модульного теста на уровне класса обычно используется фиктивная среда на основе динамического прокси, такая как MOQ или FakeItEasy.

учитывая реализацию:

public interface IDependency {
    void Foo(string bar); 
}

public class SomeClass
{
    private readonly IDependency dependency;

    public SomeClass(IDependency dependency)
    {
        this.dependency = dependency;
    } 

    public void SomeMethod(string arg)
    {
        this.dependency.Foo(arg);
    }
}

тест будет выглядеть так (вариант xUnit):

public class SomeClassTest
{
    private readonly Mock<IDependency> dependency;

    private SomeClass testee;

    public SomeClassTest()
    {
        this.dependency = new Mock<IDependency>();

        this.testee = new SomeClass(this.dependency.Object);
    }

    [Fact]
    public void SomeMethod_MustPassArgumentToFoo()
    {
        const string expectedArgument = "AnyArgument;

        this.testee.SomeMethod(expectedArgument);

        this.dependency.Verify(x => x.Foo(expectedArgument));
    }
}
person BatteryBackupUnit    schedule 26.04.2015
comment
Мы не используем Ninject в наших модульных тестах, как в ответе от BatteryBackupUnit (кстати, сумасшедшее название :-)), но мы используем его в наших приемочных тестах. Приемочный тест проверяет (почти) полную функцию (без пользовательского интерфейса, базы данных или любого другого внешнего API). - person Urs; 27.04.2015
comment
@Urs спасибо за объяснение приемочных испытаний. Я изменил текст, упомянув о приемочном тестировании вместо тестирования спецификаций, потому что это более широко известно и имеет более точное определение. - person BatteryBackupUnit; 27.04.2015

В JustMock встроен NInject, а также основанный на нем мока-контейнер. .

Внедрение макетов зависимостей выполняется автоматически при первом получении экземпляра:

var container = new MockingContainer<ClassUnderTest>();
var testee = container.Instance;

Кроме того, вы можете использовать синтаксис NInject для тонкого управления поведением инъекции, а также синтаксис JustMock для настройки фиктивного поведения.

person Stefan Dragnev    schedule 07.05.2015