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

时间:2016-04-11 15:04:53

标签: c# unit-testing autofixture

假设我想在单元测试中调用一个匿名类型来返回 -

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

Autofixture可以生成匿名类型吗?如果是这样,语法是什么?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

作为@MarkSeemann pointed out,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);
相关问题