簡體   English   中英

Autofixture可以創建一個匿名類型嗎?

[英]Can Autofixture create an anonymous type?

假設我想在單元測試中調用以返回一個看起來像這樣的匿名類型 -

var anonymousType = { id = 45, Name="MyName", Description="Whatever" }

Autofixture可以生成anonymousType嗎? 如果是這樣,語法是什么?

不,AutoFixture不支持匿名類型,因為它們是使用它們的庫的內部。

正如@MarkSeemann所指出的 ,AutoFixture 不能支持匿名類型。

關於AutoFixture和動態的注釋

這可能不適用於您的具體情況,但我認為值得一提的是,如果您需要在測試中創建動態類型對象的實例 - 而您並不關心它們的特定狀態 - 您可以配置AutoFixture來創建DynamicObject實例響應您在其上調用的任何屬性或方法。

這是一個例子:

public class DynamicCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customizations.Insert(
            0,
            new FilteringSpecimenBuilder(
                new FixedBuilder(new AnythingObject()),
                new ExactTypeSpecification(typeof(object))));
    }

    private class AnythingObject : DynamicObject
    {
        public override bool TryGetMember(
            GetMemberBinder binder,
            out object result)
        {
            result = new AnythingObject();
            return true;
        }

        public override bool TryInvokeMember(
            InvokeMemberBinder binder,
            object[] args,
            out object result)
        {
            result = new AnythingObject();
            return true;
        }
    }
}

在這種情況下, AnythingObject只是為它接收調用的任何屬性或方法返回一個新的自身實例。 這可以讓你說例如:

var fixture = new Fixture();
fixture.Customize(new DynamicCustomization());

var foo = fixture.Create<dynamic>();

Assert.NotNull(foo.Bar);
Assert.NotNull(foo.Baz());

另一種選擇 - 雖然更脆弱 - 可能是使用AutoFixture為特定屬性創建值。 在這種情況下,您必須將Fixture對象傳遞給AnythingObject ,如下例所示:

public class DynamicCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customizations.Insert(
            0,
            new FilteringSpecimenBuilder(
                new FixedBuilder(new AnythingObject(fixture)),
                new ExactTypeSpecification(typeof(object))));
    }

    private class AnythingObject : DynamicObject
    {
        private readonly SpecimenContext context;

        public AnythingObject(ISpecimenBuilder builder)
        {
            context = new SpecimenContext(builder);
        }

        public override bool TryGetMember(
            GetMemberBinder binder,
            out object result)
        {
            if (binder.Name == "Bar")
            {
                result = context.Resolve(typeof(string));
            }
            else
            {
                result = new AnythingObject(context.Builder);
            }

            return true;
        }

        public override bool TryInvokeMember(
            InvokeMemberBinder binder,
            object[] args,
            out object result)
        {
            result = new AnythingObject(context.Builder);
            return true;
        }
    }
}

在這里,我們正在尋找一個名為"Bar"的屬性並為其提供一個string ,而其他所有內容只是獲取AnythingObject一個實例。 所以我們可以說:

var fixture = new Fixture();
fixture.Customize(new DynamicCustomization());

var foo = fixture.Create<dynamic>();

Assert.IsType<string>(foo.Bar);
Assert.NotNull(foo.Baz);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM