Skip to content

Instantly share code, notes, and snippets.

@aivascu
Last active January 31, 2022 13:02
Show Gist options
  • Save aivascu/1138df84bdf3a9ceb4134373021b14ec to your computer and use it in GitHub Desktop.
Save aivascu/1138df84bdf3a9ceb4134373021b14ec to your computer and use it in GitHub Desktop.
AutoFixture Freezing behavior
internal class FreezingBehavior : ISpecimenBuilderTransformation
{
public FreezingBehavior(IRequestSpecification specification)
{
this.specification = specification ?? throw new ArgumentNullException(nameof(specification));
}
public ISpecimenBuilderNode Transform(ISpecimenBuilder builder)
{
return new FreezingNode(builder, specification);
}
}
internal class FreezingNode : ISpecimenBuilderNode
{
private readonly ISpecimenBuilder builder;
private readonly IRequestSpecification specification;
private CompositeSpecimenBuilder frozenBuilders = new CompositeSpecimenBuilder();
public FreezingNode(ISpecimenBuilder builder, IRequestSpecification specification)
{
this.builder = builder ?? throw new ArgumentNullException(nameof(builder));
this.specification = specification ?? throw new ArgumentNullException(nameof(specification));
}
public ISpecimenBuilderNode Compose(IEnumerable<ISpecimenBuilder> builders)
{
var composedBuilder = new CompositeSpecimenBuilder(builders);
return new FreezingNode(composedBuilder, specification);
}
public object Create(object request, ISpecimenContext context)
{
if (!specification.IsSatisfiedBy(request))
{
return builder.Create(request, context);
}
object result = frozenBuilders.Create(request, null);
if (result is not NoSpecimen)
{
return result;
}
result = builder.Create(request, context);
frozenBuilders = new CompositeSpecimenBuilder(
frozenBuilders,
new FilteringSpecimenBuilder(
new FixedBuilder(result),
new EqualRequestSpecification(request)));
return result;
}
public IEnumerator<ISpecimenBuilder> GetEnumerator()
{
yield return builder;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
internal class InterfaceSpecification : IRequestSpecification
{
public bool IsSatisfiedBy(object request)
{
return request is Type type
&& type.IsInterface;
}
}
public class Tests
{
[Fact]
public void Foo()
{
Fixture fixture = new Fixture();
fixture.Behaviors.Add(new FreezingBehavior(new InterfaceSpecification()));
fixture.Customize(new AutoMoqCustomization());
IMyInterface myMock = fixture.Create<IMyInterface>();
IMyInterface myMock1 = fixture.Create<IMyInterface>();
IMyInterface myMock2 = fixture.Create<IMyInterface>();
IMyInterface myMock21 = fixture.Create<IMyInterface>();
Assert.NotNull(myMock);
Assert.Same(myMock, myMock1);
Assert.Same(myMock2, myMock21);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment