简体   繁体   English

Autofixture可以创建一个匿名类型吗?

[英]Can Autofixture create an anonymous type?

Suppose I'd like a call in a unit test to return an anonymous type that looks like this - 假设我想在单元测试中调用以返回一个看起来像这样的匿名类型 -

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

Could Autofixture generate anonymousType? Autofixture可以生成anonymousType吗? If so, what's the syntax? 如果是这样,语法是什么?

不,AutoFixture不支持匿名类型,因为它们是使用它们的库的内部。

As @MarkSeemann pointed out , AutoFixture cannot support anonymous types. 正如@MarkSeemann所指出的 ,AutoFixture 不能支持匿名类型。

Notes on AutoFixture and dynamic 关于AutoFixture和动态的注释

This may not apply to your specific case, but I think it's worth mentioning that if you need to create instances of dynamically typed objects in your tests – and you aren't concerned about their particular state – you can configure AutoFixture to create instances of DynamicObject that respond to any property or method that you invoke on them. 这可能不适用于您的具体情况,但我认为值得一提的是,如果您需要在测试中创建动态类型对象的实例 - 而您并不关心它们的特定状态 - 您可以配置AutoFixture来创建DynamicObject实例响应您在其上调用的任何属性或方法。

Here's an example: 这是一个例子:

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

In this case the AnythingObject simply returns a new instance of itself for any property or method it receives a call for. 在这种情况下, AnythingObject只是为它接收调用的任何属性或方法返回一个新的自身实例。 This would allow you to say for example: 这可以让你说例如:

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

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

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

Another alternative – albeit more fragile – could be to use AutoFixture to create values for specific properties . 另一种选择 - 虽然更脆弱 - 可能是使用AutoFixture为特定属性创建值。 In that case you would have to pass the Fixture object to AnythingObject like in this example: 在这种情况下,您必须将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;
        }
    }
}

Here we're looking for a property named "Bar" and provide a string for it, while everything else will just get an instance of AnythingObject . 在这里,我们正在寻找一个名为"Bar"的属性并为其提供一个string ,而其他所有内容只是获取AnythingObject一个实例。 So we can say: 所以我们可以说:

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