Verification of a function call on a mock object not matched when a params array is used
I have the following test:
[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>()))));
}
As you can see I am mocking the real behavior of the kernel by calling the facilitiy's Init(IKernel, IConfiguration)
method which in turns calls the protected Init()
method.
protected override void Init()
{
Kernel.ProxyFactory.AddInte开发者_运维技巧rceptorSelector(new LoggingModelInterceptorsSelector());
Kernel.Register(Component.For<LoggingInterceptor>());
}
I expected that the verification would pass but it does not. If I verify that the Kernel.Register was called at all with It.IsAny<LoggingInterceptor>()
the test passes.
It seems like you are testing way too much here. You are effectively reimplmenting a lot of Windsor's internals by piping calls from AddFacility
to LoggingInterceptionFacility.Init
.
All you really need to test is the fact that your facility calls Register
on the kernel and assume that Windsor does the right thing. After all, it has unit tests of its own ;)
After doing that, the test becomes much more readable, which I consider the most important aspect.
[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>);
}
EDIT Calls to Component.For
return different instances between setup and execution. I updated the code to reflect that and have the verification check the type of the component.
精彩评论