Как правильно использовать Ninject RhinoMocksMockingKernel для тестирования класса, который имеет два аргумента конструктора одного типа? - PullRequest
1 голос
/ 30 ноября 2011

Я тестирую класс, который имеет две зависимости от IFoo. Оба экземпляра IFoo должны быть объектами MOCK, чтобы я мог VerifyExpectations для каждого. Каждый экземпляр создается и управляется RhinoMocksMockingKernel.

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

Мне также кажется, что я не совсем понимаю, как правильно настроить RhinoMocksMockingKernel для этого случая.

Я знаю, что могу использовать dep1.AssertWasCalled ... против dep1.VerifyAllExpectations ().

Вот пример кода.

public interface IFoo
{
    void DoX();
    void DoY();
}

public class SubjectUnderTest
{

    private readonly IFoo dep1;
    private readonly IFoo dep2;

    public void DoWork()
    {
        dep1.DoX();
        dep2.DoY();
    }

    public SubjectUnderTest(IFoo dep1, IFoo dep2)
    {
        this.dep2 = dep2;
        this.dep1 = dep1;            
    }
}

[TestFixture]
public class Tests
{
    [Test]
    public void DoWork_DoesX_And_DoesY()
    {
        var kernel = new Ninject.MockingKernel.RhinoMock.RhinoMocksMockingKernel();
        var dep1 = kernel.Get<IFoo>();
        var dep2 = kernel.Get<IFoo>();

        // tried this binding but it doesnt seem to work
        kernel.Bind<SubjectUnderTest>()
            .ToSelf()
            .WithConstructorArgument("dep1", dep1)
            .WithConstructorArgument("dep2", dep2);

        var sut = kernel.Get<SubjectUnderTest>();

        dep1.Expect(it => it.DoX());
        dep2.Expect(it => it.DoY());

        sut.DoWork();

        dep1.VerifyAllExpectations();
        dep2.VerifyAllExpectations();
    }
}

Ответы [ 2 ]

2 голосов
/ 02 декабря 2011

Как сказал Рибер, вам не следует использовать контейнер IOC в своих тестах таким образом. Тем не менее, я все равно отвечу на вопрос, если у вас есть эта проблема в обычном коде. Вы можете использовать атрибут Named, как показано в этом другом вопросе stackoverflow: Как использовать Ninject именованные привязки с DependencyResolver и PropertyInjection

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

public void SubjectUnderTest([Named("Alpha")] IFoo alpha, [Named("Beta")]) {
  ...
}

И привязки должны быть зарегистрированы как описано в этом посте: Как использовать Ninject Named Bindings с DependencyResolver и PropertyInjection

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

0 голосов
/ 03 декабря 2011

Итак, я нашел способ проверить исключения для dep1 и dep2, но я не смог использовать AutoMockingKernel для управления и создания dep1 и dep1.

Вот код, который я придумал.

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

Вот мой текущий код ... lameo ...

[TestFixture]
public class Tests
{
    [Test]
    public void DoWork_DoesX_And_DoesY()
    {
        var kernel = new Ninject.MockingKernel.RhinoMock.RhinoMocksMockingKernel();
        var dep1 = MockRepository.GenerateMock<IFoo>();
        var dep2 = MockRepository.GenerateMock<IFoo>();

        kernel.Bind<IFoo>().ToMethod((ctx) => dep1).When((ctx) => ctx.Target.Name.StartsWith("dep1"));
        kernel.Bind<IFoo>().ToMethod((ctx) => dep2).When((ctx) => ctx.Target.Name.StartsWith("dep2"));

        var sut = kernel.Get<SubjectUnderTest>();

        dep1.Expect(it => it.DoX());
        dep2.Expect(it => it.DoY());

        sut.DoWork();

        dep1.VerifyAllExpectations();
        dep2.VerifyAllExpectations();
    }
}
...