【问题标题】:Ploeh AutoFixture was unable to create an instance from System.Runtime.Serialization.ExtensionDataObjectPloeh AutoFixture 无法从 System.Runtime.Serialization.ExtensionDataObject 创建实例
【发布时间】:2013-03-18 14:11:36
【问题描述】:

我们有一个引用 WCF 服务的 MVC 项目。这些引用将 (ExtensionDataObject)ExtensionData 属性添加到每个 DTO 和 Response 对象,现在 AutoFixture 无法创建这些类型的匿名实例。

例子:

public partial class SearchResultsDto : object, 
    System.Runtime.Serialization.IExtensibleDataObject, 
    System.ComponentModel.INotifyPropertyChanged {

    [System.NonSerializedAttribute()]
    private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

    [global::System.ComponentModel.BrowsableAttribute(false)]
    public System.Runtime.Serialization.ExtensionDataObject ExtensionData {
        get {
                return this.extensionDataField;
            }
        set {
                this.extensionDataField = value;
            }
        }
    }

代码:

_fixture = new Fixture().Customize(new AutoMoqCustomization());
var dto = _fixture.CreateAnonymous<SearchResultsDto>();

例外:

Ploeh.AutoFixture.ObjectCreationException: Ploeh.AutoFixture.ObjectCreationException:AutoFixture 无法 从创建一个实例 System.Runtime.Serialization.ExtensionDataObject,很可能是因为 它没有公共构造函数,是抽象或非公共类型..

问题:有没有办法在 AutoFixture 中注册此对象,以便将其实例化为 null 或其他任何内容,这可以让我对所有具有 ExtensionData 属性的对象执行 CreateAnonymous

【问题讨论】:

    标签: c# .net autofixture


    【解决方案1】:

    最简单的方法是:

    fixture.Register<ExtensionDataObject>(() => null);
    

    这向 AutoFixture 注册了一种初始化所有 ExtensionDataObject 的特定方式,并给出了 Func。在这种情况下,Func 总是返回 null,所以你可以开始了。

    【讨论】:

    • 这很好用。查克的答案最终和这个答案一样吗?
    【解决方案2】:

    我希望有人会发现它很有用,我已经设法让它与 PropertyTypeOmitter 类一起使用 this thread

    public void Test()
    {
        var fixture = new Fixture();
        fixture.Customizations.Add(
            new PropertyTypeOmitter(
                typeof(ExtensionDataObject)));
    
        var person = fixture.CreateAnonymous<Person>();
    }
    
    internal class PropertyTypeOmitter : ISpecimenBuilder
    {
        private readonly Type type;
    
        internal PropertyTypeOmitter(Type type)
        {
            if (type == null)
                throw new ArgumentNullException("type");
    
            this.type = type;
        }
    
        internal Type Type
        {
            get { return this.type; }
        }
    
        public object Create(object request, ISpecimenContext context)
        {
            var propInfo = request as PropertyInfo;
            if (propInfo != null && propInfo.PropertyType == type)
                return new OmitSpecimen();
    
            return new NoSpecimen();
        }
    }
    

    【讨论】:

    • 自 AutoFixture 3.x 以来,最后一行代码触发了由构造函数调用被标记为过时引起的警告。为了删除它,将其更改为:new NoSpecimen()
    【解决方案3】:

    为了使其更干燥和 CTRL+C 友好,这里是 Spiros Dellaportases(谢谢!)答案包含在夹具定制中:

    public class OmitExtensionDataObjectPropertyCustomization : ICustomization
    {
        public void Customize(IFixture fixture)
        {
            fixture.Register<ExtensionDataObject>(() => null);
        }
    }
    

    【讨论】:

    • 你为什么要抄别人的答案?
    • 解释在答案的第一句话中。应该帮助人们保持他们的代码干燥,特别是如果他们是 AutoFixture 的新手。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    相关资源
    最近更新 更多