如何在SimpleInjector 2.6.1+中对开放的通用装饰器链进行单元测试 [英] How to unit test open generic decorator chains in SimpleInjector 2.6.1+

查看:71
本文介绍了如何在SimpleInjector 2.6.1+中对开放的通用装饰器链进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用SimpleInjector给出以下开放的通用deocrator链:

Given the following open generic deocrator chain using SimpleInjector:

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,我可以使用以下方法进行单元测试以断言装饰链代码:

With SimpleInjector 2.4.0, I was able to unit test this to assert the decoration chain using the following code:

[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)

After updating to SimpleInjector 2.6.1, this unit test fails. It seems that InstanceProducer.Registration.ImplementationType now returns the first decoration handler rather than the decorated handler (meaning, it returns typeof(QueryNotNullDecorator<HandleFakeQueryWithoutValidator,string>) instead of typeof(HandleFakeQueryWithoutValidator).

另外, InstanceProducer.GetRelationships()不再返回链中的所有装饰器,而仅返回第一个装饰器。

Also, InstanceProducer.GetRelationships() no longer returns all of the decorators in the chain. it also only returns the first decorator.

这是一个错误,如果没有,我们如何使用SimpleInjector 2.6.1+对开放的通用装饰器链进行单元测试?

Is this a bug and, if not, how can we unit test open generic decorator chains using SimpleInjector 2.6.1+?

推荐答案

详细信息可用于依赖关系图的版本在2.6中得到了很大的改进。您可以使用以下代码实现相同的目的:

The detail available for the dependency graph has been greatly improved in 2.6. You can achieve the same thing with this code:

[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);
}

您可以找到更多信息此处

请注意:我认为您有强制性依赖-您在单例装饰器中有一个临时处理程序...

Please note: I think you have a captive dependency - you have a transient handler inside of a singleton decorator ...

[Fact]
public void Container_Always_ContainsNoDiagnosticWarnings()
{
    var container = this.ContainerFactory();

    container.Verify();

    var results = Analyzer.Analyze(container);

    Assert.False(results.Any());
}

这篇关于如何在SimpleInjector 2.6.1+中对开放的通用装饰器链进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆