Despite the fact that it is not currently built-in, itβs easy to write a general-purpose decorator that freezes objects when they leave the automatic adaptation tree:
public class MemoizingBuilder : ISpecimenBuilder { private readonly ISpecimenBuilder builder; private readonly ConcurrentDictionary<object, object> instances; public MemoizingBuilder(ISpecimenBuilder builder) { this.builder = builder; this.instances = new ConcurrentDictionary<object, object>(); } public object Create(object request, ISpecimenContext context) { return this.instances.GetOrAdd( request, r => this.builder.Create(r, context)); } }
Note that it decorates another ISpecimenBuilder , but remembers all the values ββbefore returning them. If the same request arrives again, it will return a memoized value.
While you cannot extend AutoMoqCustomization , you can replicate what it does (these are just two lines of code) and use MemoizingBuilder around it:
public class AutoFreezeMoq : ICustomization { public void Customize(IFixture fixture) { if (fixture == null) throw new ArgumentNullException("fixture"); fixture.Customizations.Add( new MemoizingBuilder( new MockPostprocessor( new MethodInvoker( new MockConstructorQuery())))); fixture.ResidueCollectors.Add(new MockRelay()); } }
Use AutoFreezeMoq instead of AutoMoqCustomization . It will freeze all mocks and all interfaces and abstract base classes created from these mocks.
public class AutoMoqDataAttribute : AutoDataAttribute { public AutoMoqDataAttribute() : base(new Fixture().Customize(new AutoFreezeMoq())) { } }
Mark seemann
source share