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? If so, what's the syntax?
No, AutoFixture doesn't support anonymous types, as they're internal to the library that uses them.
As @MarkSeemann pointed out, AutoFixture cannot support anonymous types.
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.
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. 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. In that case you would have to pass the Fixture
object to AnythingObject
like in this example:
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
. 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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With