Autofixture 可以创建匿名类型吗?
Can Autofixture create an anonymous type?
假设我想在单元测试中调用 return 匿名类型,如下所示 -
var anonymousType = { id = 45, Name="MyName", Description="Whatever" }
Autofixture可以生成anonymousType吗?如果是这样,语法是什么?
不,AutoFixture 不支持匿名类型,因为它们在使用它们的库内部。
由于@MarkSeemann ,AutoFixture 不能 支持匿名类型。
关于 AutoFixture 和 dynamic
的注意事项
这可能不适用于您的特定情况,但我认为值得一提的是,如果您需要在测试中创建 动态类型对象 的实例 – 而您不需要关心它们的特定状态——你可以配置AutoFixture来创建DynamicObject
的实例来响应any属性或方法你调用它们。
这是一个例子:
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
只是 returns 它自己的一个新实例,用于任何 属性 或它收到调用的方法。这将允许您说例如:
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);
假设我想在单元测试中调用 return 匿名类型,如下所示 -
var anonymousType = { id = 45, Name="MyName", Description="Whatever" }
Autofixture可以生成anonymousType吗?如果是这样,语法是什么?
不,AutoFixture 不支持匿名类型,因为它们在使用它们的库内部。
由于@MarkSeemann
关于 AutoFixture 和 dynamic
的注意事项这可能不适用于您的特定情况,但我认为值得一提的是,如果您需要在测试中创建 动态类型对象 的实例 – 而您不需要关心它们的特定状态——你可以配置AutoFixture来创建DynamicObject
的实例来响应any属性或方法你调用它们。
这是一个例子:
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
只是 returns 它自己的一个新实例,用于任何 属性 或它收到调用的方法。这将允许您说例如:
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);