使用Ninject RhinoMocksMockingKernel测试具有两个相同类型的构造函数参数的类的正确方法是什么?

时间:2011-11-29 22:03:19

标签: c# unit-testing ninject rhino-mocks

我正在测试一个对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 个答案:

答案 0 :(得分:2)

正如ryber所说,你不应该在测试中使用你的IOC容器。但是,如果您在普通代码中遇到此问题,我仍会回答这个问题。您可以使用Named属性,如此其他stackoverflow问题所示:How To Use Ninject Named Bindings With DependencyResolver and PropertyInjection

在该示例中,Named属性位于函数的上方,但您也可以将其放在参数旁边,以指定应使用哪个属性。 E.g。

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

绑定应按照此帖中所述进行注册:How To Use Ninject Named Bindings With DependencyResolver and PropertyInjection

您也可以使用ToMethod绑定手动创建对象。

答案 1 :(得分:0)

所以我找到了一种方法来验证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();
    }
}