[英]How to unit test decorator registrations using SimpleInjector 3+?
[英]How to unit test open generic decorator chains in SimpleInjector 2.6.1+
给定以下使用SimpleInjector的开放式通用deocrator链:
container.RegisterManyForOpenGeneric(typeof(IHandleQuery<,>), assemblies);
container.RegisterDecorator(
typeof(IHandleQuery<,>),
typeof(ValidateQueryDecorator<,>)
);
container.RegisterSingleDecorator(
typeof(IHandleQuery<,>),
typeof(QueryLifetimeScopeDecorator<,>)
);
container.RegisterSingleDecorator(
typeof(IHandleQuery<,>),
typeof(QueryNotNullDecorator<,>)
);
使用SimpleInjector 2.4.0,我能够使用以下代码对此进行单元测试以断言装饰链:
[Fact]
public void RegistersIHandleQuery_UsingOpenGenerics_WithDecorationChain()
{
var instance = Container
.GetInstance<IHandleQuery<FakeQueryWithoutValidator, string>>();
InstanceProducer registration = Container.GetRegistration(
typeof(IHandleQuery<FakeQueryWithoutValidator, string>));
instance.ShouldNotBeNull();
registration.Registration.ImplementationType
.ShouldEqual(typeof(HandleFakeQueryWithoutValidator));
registration.Registration.Lifestyle.ShouldEqual(Lifestyle.Transient);
var decoratorChain = registration.GetRelationships()
.Select(x => new
{
x.ImplementationType,
x.Lifestyle,
})
.Reverse().Distinct().ToArray();
decoratorChain.Length.ShouldEqual(3);
decoratorChain[0].ImplementationType.ShouldEqual(
typeof(QueryNotNullDecorator<FakeQueryWithoutValidator, string>));
decoratorChain[0].Lifestyle.ShouldEqual(Lifestyle.Singleton);
decoratorChain[1].ImplementationType.ShouldEqual(
typeof(QueryLifetimeScopeDecorator<FakeQueryWithoutValidator, string>));
decoratorChain[1].Lifestyle.ShouldEqual(Lifestyle.Singleton);
decoratorChain[2].ImplementationType.ShouldEqual(
typeof(ValidateQueryDecorator<FakeQueryWithoutValidator, string>));
decoratorChain[2].Lifestyle.ShouldEqual(Lifestyle.Transient);
}
更新到SimpleInjector 2.6.1后,此单元测试失败。 似乎InstanceProducer.Registration.ImplementationType
现在返回第一个装饰处理程序而不是装饰处理程序(意思是,它返回typeof(QueryNotNullDecorator<HandleFakeQueryWithoutValidator,string>)
而不是typeof(HandleFakeQueryWithoutValidator)
。
此外, InstanceProducer.GetRelationships()
不再返回链中的所有装饰器。 它也只返回第一个装饰器。
这是一个错误,如果没有,我们如何使用SimpleInjector 2.6.1+单元测试开放的通用装饰链?
依赖图的可用细节在2.6中有了很大的改进。 您可以使用以下代码实现相同的功能:
[Fact]
public void RegistersIHandleQuery_UsingOpenGenerics_WithDecorationChain()
{
var container = this.ContainerFactory();
var instance = container
.GetInstance<IHandleQuery<FakeQueryWithoutValidator, string>>();
var registration = (
from currentRegistration in container.GetCurrentRegistrations()
where currentRegistration.ServiceType ==
typeof(IHandleQuery<FakeQueryWithoutValidator, string>)
select currentRegistration.Registration)
.Single();
Assert.Equal(
typeof(QueryNotNullDecorator<FakeQueryWithoutValidator, string>),
registration.ImplementationType);
Assert.Equal(Lifestyle.Singleton, registration.Lifestyle);
registration = registration.GetRelationships().Single().Dependency.Registration;
Assert.Equal(
typeof(QueryLifetimeScopeDecorator<FakeQueryWithoutValidator, string>),
registration.ImplementationType);
Assert.Equal(Lifestyle.Singleton, registration.Lifestyle);
registration = registration.GetRelationships().Single().Dependency.Registration;
Assert.Equal(
typeof(ValidateQueryDecorator<FakeQueryWithoutValidator, string>),
registration.ImplementationType);
Assert.Equal(Lifestyle.Transient, registration.Lifestyle);
}
您可以在此处找到更多信息
请注意:我认为你有一个俘虏依赖 - 你在单身装饰器内有一个瞬态处理程序......
[Fact]
public void Container_Always_ContainsNoDiagnosticWarnings()
{
var container = this.ContainerFactory();
container.Verify();
var results = Analyzer.Analyze(container);
Assert.False(results.Any());
}
Qujck是对的。 我们极大地改进了注册和KnownDependency图的构建方式,特别是改进了诊断并使用户更容易查询注册。 所以这不是一个bug; 这是一个突破性的变化。 然而,我们没想到任何人会受到这种影响,这就是为什么我们在次要版本中进行了更改。 对不起,你不得不偶然发现这个变化,但至少它只是破坏的测试代码。
在以前的版本中,当添加了装饰器时,KnownDependency对象的图形被展平。 这使得难以查询和可视化对象图。 在v2.6中,从诊断API的角度来看,就好像装饰器是“真正的”注册。 这意味着InstanceProducer和Registration对象现在显示返回的真实类型及其生活方式。
更清楚,但诊断API发生了重大变化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.