Last active
January 31, 2022 13:02
-
-
Save aivascu/1138df84bdf3a9ceb4134373021b14ec to your computer and use it in GitHub Desktop.
AutoFixture Freezing behavior
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class InterfaceSpecification : IRequestSpecification | |
{ | |
public bool IsSatisfiedBy(object request) | |
{ | |
return request is Type type | |
&& type.IsInterface; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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