Unit testing 当使用params数组时,验证对不匹配的模拟对象的函数调用

Unit testing 当使用params数组时,验证对不匹配的模拟对象的函数调用,unit-testing,castle-windsor,moq,windsor-facilities,Unit Testing,Castle Windsor,Moq,Windsor Facilities,我有以下测试: [Test] public void VerifyThat_WhenInitializingTheLoggingInterceptionFacility_TheLoggingInterceptorIsAdded() { var kernel = new Mock<IKernel>(MockBehavior.Loose) { DefaultValue = DefaultValue.Mock

我有以下测试:

[Test]
public void VerifyThat_WhenInitializingTheLoggingInterceptionFacility_TheLoggingInterceptorIsAdded()
{
    var kernel = new Mock<IKernel>(MockBehavior.Loose)
            {
                DefaultValue = DefaultValue.Mock
            };
    kernel.Setup(k => k.AddFacility<LoggingInterceptionFacility>())
                .Returns(kernel.Object)
                .Callback(() => ((IFacility)new LoggingInterceptionFacility()).Init(kernel.Object, Mock.Of<IConfiguration>()));

    kernel.Setup(k => k.Register(It.IsAny<IRegistration[]>()))
                  .Returns(kernel.Object)
                  .Verifiable();

    kernel.Object.AddFacility<LoggingInterceptionFacility>();

    kernel.Verify(k => k.Register(It.Is<IRegistration[]>(r => r.Contains(Component.For<LoggingInterceptor>()))));
}
我原以为核查会通过,但没有通过。如果我验证是否使用
It.IsAny()
调用了Kernel.Register,则测试通过。

我在这里不匹配的是什么?有没有办法让这个测试通过呢?

看来你在这里测试得太多了。通过从
AddFacility
LoggingInterceptionFacility.Init
的管道调用,您可以有效地重新植入大量温莎内部构件

您真正需要测试的是,您的设备在内核上调用
Register
,并假设Windsor做了正确的事情。毕竟,它有自己的单元测试;)

这样做后,测试变得更加可读,我认为这是最重要的方面。

[Test]
public void VerifyThat_WhenInitializingTheLoggingInterceptionFacility_TheLoggingInterceptorIsAdded()
{
    var kernel = new Mock<IKernel>();

    kernel.Setup(k => k.Register(It.IsAny<IRegistration[]>()))
                  .Returns(kernel.Object)
                  .Verifiable();
    //Explicit interface implementation requires casting to the interface
    ((IFacility)new LoggingInterceptionFacility()).Init(kernel.Object, Mock.Of<IConfiguration>().Object);
    //verify the type of registration here
    kernel.Verify(k => k.Register(It.Is<IRegistration[]>(r => r[0] is ComponentRegistration<LoggingInterceptor>);
}
[测试]
在启动日志拦截设施时添加日志拦截器()的公共无效验证
{
var kernel=newmock();
kernel.Setup(k=>k.Register(It.IsAny()))
.Returns(kernel.Object)
.可验证();
//显式接口实现需要转换到接口
((IFacility)新的LoggingInterceptionFacility()).Init(kernel.Object,Mock.Of().Object);
//在此处验证注册类型
Verify(k=>k.Register(It.Is(r=>r[0]是ComponentRegistration));
}

编辑对
组件的调用。For
在安装和执行之间返回不同的实例。我更新了代码以反映这一点,并让验证人员检查组件的类型。

似乎您在这里测试的太多了。通过从
AddFacility
LoggingInterceptionFacility.Init

您真正需要测试的是,您的设备在内核上调用
Register
,并假设Windsor做了正确的事情。毕竟,它有自己的单元测试;)

这样做后,测试变得更加可读,我认为这是最重要的方面。

[Test]
public void VerifyThat_WhenInitializingTheLoggingInterceptionFacility_TheLoggingInterceptorIsAdded()
{
    var kernel = new Mock<IKernel>();

    kernel.Setup(k => k.Register(It.IsAny<IRegistration[]>()))
                  .Returns(kernel.Object)
                  .Verifiable();
    //Explicit interface implementation requires casting to the interface
    ((IFacility)new LoggingInterceptionFacility()).Init(kernel.Object, Mock.Of<IConfiguration>().Object);
    //verify the type of registration here
    kernel.Verify(k => k.Register(It.Is<IRegistration[]>(r => r[0] is ComponentRegistration<LoggingInterceptor>);
}
[测试]
在启动日志拦截设施时添加日志拦截器()的公共无效验证
{
var kernel=newmock();
kernel.Setup(k=>k.Register(It.IsAny()))
.Returns(kernel.Object)
.可验证();
//显式接口实现需要转换到接口
((IFacility)新的LoggingInterceptionFacility()).Init(kernel.Object,Mock.Of().Object);
//在此处验证注册类型
Verify(k=>k.Register(It.Is(r=>r[0]是ComponentRegistration));
}

EDIT调用
组件。For
在安装和执行之间返回不同的实例。我更新了代码以反映这一点,并让验证人员检查组件的类型。

这里你错了。首先,你不能调用Init(IKernel,IConfiguration)直接。你必须强制转换到IFacility才能做到这一点。其次,我在这里隔离windsor的行为。无论它是否正确编写,我都会像预期的用例一样自然地使用它。但是我不知道该组件。For返回一个不实现==或等于()的对象。我对您的答案有复杂的感觉。
组件。因为
是一个工厂,每次都返回一个新实例。默认情况下,对象通过引用进行比较,并且由于它们不是不可变的值对象,所以它们不会覆盖
对象。Equals
来进行值比较。不,您测试的所有内容都是反向工程在测试方法开始时正确编辑Castle Windsor代码。如果您想要更好的集成测试,请将Castle视为黑盒,不要模拟它,设置日志记录器,然后验证它是否确实记录了内容。这样可以验证整个解决方案是否有效。您的代码未编译。您无法将模拟传递给Init().你把我卖了。你错了。首先,你不能调用Init(IKernel,IConfiguration)直接。你必须强制转换到IFacility才能做到这一点。其次,我在这里隔离windsor的行为。无论它是否正确编写,我都会像预期的用例一样自然地使用它。但是我不知道该组件。For返回一个不实现==或等于()的对象。我对您的答案有复杂的感觉。
组件。因为
是一个工厂,每次都返回一个新实例。默认情况下,对象通过引用进行比较,并且由于它们不是不可变的值对象,所以它们不会覆盖
对象。Equals
来进行值比较。不,您测试的所有内容都是反向工程在测试方法开始时正确编辑Castle Windsor代码。如果您想要更好的集成测试,请将Castle视为黑盒,不要模拟它,设置日志记录器,然后验证它是否确实记录了内容。这样可以验证整个解决方案是否有效。您的代码未编译。您无法将模拟传递给Init().你把我卖了。