c# – AutoFixture:配置Open Generics Specimen Builder
我有一个使用Open Generics的对象模型(是的,是的,现在我有两个问题;这就是为什么我在这里:): –
public interface IOGF<T> { } class C { } class D { readonly IOGF<C> _ogf; public D( IOGF<C> ogf ) { _ogf = ogf; } } 我正在尝试让AutoFixture生成上面的D的匿名实例.然而,就其自身而言,AutoFixture没有用于构建IOGF的内置策略<>因此我们观察到: public class OpenGenericsBinderDemo { [Fact] public void X() { var fixture = new Fixture(); Assert.Throws<Ploeh.AutoFixture.ObjectCreationException>( () => fixture.CreateAnonymous<D>() ); } 基本信息是:
我很高兴为它提供一个具体的实现: public class OGF<T> : IOGF<T> { public OGF( IX x ) { } } public interface IX { } public class X : IX { } 以及相关的绑定: fixture.Register<IX,X>(); 我如何(或者我应该以这种方式查看问题?)使以下测试通过? public class OpenGenericsLearning { [Fact] public void OpenGenericsDontGetResolved() { var fixture = new Fixture(); fixture.Inject<IX>( fixture.Freeze<X>() ); // TODO register or do something that will provide // OGF<C> to fulfill D's IOGF<C> requirement Assert.NotNull( fixture.CreateAnonymous<D>()); } } (在codeplex网站上有关于此问题的讨论和问题 – 我只需要快速了解这一点,如果这只是一个坏主意和/或我错过了某些内容,我可以删除它 编辑2 :(另请参阅Mark的回答评论)这里(公认的设计)上下文是对一个大的“几乎完整的系统”系统测试对象图而不是一个小的(受控/易于理解:)对或三元组的验收测试单元或集成测试场景中的类.正如在自我问题括号中所提到的那样,我并不完全相信这种类型的测试甚至有意义. 解决方法
您可以创建一个自定义,其工作方式如下:
public class AnOpenGenericsBinderDemo { [Fact] public void RegisteringAGenericBinderShouldEnableResolution() { var fixture = new Fixture(); fixture.Inject<IX>( fixture.Freeze<X>() ); fixture.RegisterOpenGenericImplementation( typeof( IOGF<> ),typeof( OGF<> ) ); Assert.IsType<OGF<C>>( fixture.CreateAnonymous<D>().Ogf ); } } 并实现如下: public static class AutoFixtureOpenGenericsExtensions { public static void RegisterOpenGenericImplementation( this IFixture that,Type serviceType,Type componentType ) { if ( !serviceType.ContainsGenericParameters ) throw new ArgumentException( "must be open generic","serviceType" ); if ( !componentType.ContainsGenericParameters ) throw new ArgumentException( "must be open generic","componentType" ); // TODO verify number of type parameters is 1 in each case that.Customize( new OpenGenericsBinderCustomization( serviceType,componentType ) ); } public class OpenGenericsBinderCustomization : ICustomization { readonly Type _serviceType; readonly Type _componentType; public OpenGenericsBinderCustomization( Type serviceType,Type componentType ) { _serviceType = serviceType; _componentType = componentType; } void ICustomization.Customize( IFixture fixture ) { fixture.Customizations.Add( new OpenGenericsSpecimenBuilder( _serviceType,_componentType ) ); } class OpenGenericsSpecimenBuilder : ISpecimenBuilder { readonly Type _serviceType; readonly Type _componentType; public OpenGenericsSpecimenBuilder( Type serviceType,Type componentType ) { _serviceType = serviceType; _componentType = componentType; } object ISpecimenBuilder.Create( object request,ISpecimenContext context ) { var typedRequest = request as Type; if ( typedRequest != null && typedRequest.IsGenericType && typedRequest.GetGenericTypeDefinition() == _serviceType ) return context.Resolve( _componentType.MakeGenericType( typedRequest.GetGenericArguments().Single() ) ); return new NoSpecimen( request ); } } } } 我假设某人有比这更好的实现和/或有内置实现. 编辑:以下是具有感知属性的更新D: class D { readonly IOGF<C> _ogf; public D( IOGF<C> ogf ) { _ogf = ogf; } public IOGF<C> Ogf { get { return _ogf; } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |