Extensions for AutoFixture and Moq
License
—
Deps
2
Install Size
—
Vulns
✓ 0
Published
Aug 7, 2025
$ dotnet add package AutoMockFixture.AnalyzerAndCodeCompletionWhile existing Mocking frameworks are great, they have many shortcoming:
mock.Setup(m => It.IsAny<int>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MyClass>())Moq the actual object has to be called explictly by doing .Object which is annyoing sometimesWhile AutoFixture helps with a lot of the setups, it does have many shortcomings, for example:
Callbase = false, as well as providing real arguments to the mock instead of mocksFoo that has a ctor argument Boo that in turn has a ctor arg of Foo )internal members, (although they are as valid as public memebers and as vital for the code funtions)Consider the following class:
class Foo
{
public Foo(Bar bar)
{
var p = new Process(); // Should not arrive here on testing
}
internal string InternalProp { get; set; }
public virtual void Method1(Bar1 bar1, Bar2 bar2){}
public virtual void Method2(Bar1 bar1, Bar2 bar2){}
}Here is the test code:
In Moq:
var mock = new Mock<Foo>(Mock.Of<Bar>()); // Will call the ctor even when callbase is false
mock.Setup(m => m.Method1(It.IsAny<Bar1>(), It.IsAny<Bar2>()));
mock.Setup(m => m.Method2(It.IsAny<Bar1>(), It.IsAny<Bar2>()));
var obj = mock.Object;
obj.Method1(Mock.Of<Bar1>(), Mock.Of<Bar2>());
mock.Verify(m => m.Method1(It.IsAny<Bar1>(), It.IsAny<Bar2>()), Times.Once());
mock.Verify(m => m.Method2(It.IsAny<Bar1>(), It.IsAny<Bar2>()), Times.Never());In AutoMockFixture:
var mockObj = new AutoMock<Foo>() // Won't call the ctor since callbase is false
.Setup(nameof(Foo.Method1), Times.Once())
.Setup(nameof(Foo.Method1), Times.Never()); // We can chain it
mockObj.Method1(Mock.Of<Bar1>(), Mock.Of<Bar2>());
mockObj.Verify();Let's say that you want to make a concrete instance of Foo but mock all arguments with callbase false, so that you can verify it uses the arguments correctly.
In AutoFixture:
var fixture = new Fixture();
var bar = fixture.Create<Mock<Bar>>(); // Assuming that you use Autofixture.AutoMoq, otherwise you need to set up all methods manually!!
bar.CallBase = false; // Autofixture.AutoMoq defaults to true
fixture.Freeze(bar.Object);
var foo = fixture.Create<Foo>();
bar.Verify(m => m.SomeMethod(It.IsAny<Bar1>(), It.IsAny<Bar2>()), Times.Once());
Assert.Equals(bar.Object.InternalProp, null); // AutoFixture ignores internal properties and methodsIn AutoMockFixture:
var fixture = new UnitFixture(); // Unit fixture is better suited for unit testing by automatically mocking all ctor args and property/field value
var foo = fixture.Create<Foo>();
fixture.On<Bar>().Verify(m => m.SomeMethod(It.IsAny<Bar1>(), It.IsAny<Bar2>()));
Assert.NotEquals(bar.Object.InternalProp, null); // AutoMockFixture sets up internal properties and methodsOr you can pass it in as a ctor arg:
var fixture = new UnitFixture();
var bar = fixture.CreateAutoMock<Bar>()
.Setup(nameof(SomeMethod), Times.Once());
fixture.Customize(new ConstructorArgumentCustomization(new ConstructorArgumentValue(bar)));
var foo = fixture.Create<Foo>();Or if you don't have an issue to freeze it then do:
var fixture = new UnitFixture();
fixture.On<Bar>().Setup(nameof(SomeMethod), Times.Once());
var foo = fixture.Create<Foo>();Let's say we have the following code (this is a contrived example of course):
class Address
{
public void SetZip(string zip){};
}
class Customer
{
public Customer(Address billingAddress, Address shippingAddress)
{
billingAddress.SetZip("11111");
shippingAddress.SetZip("11111");
}
}
class Order
{
public Order(Customer customer){}
}Now we want to create two orders and ensure that the second order has called the SetZip() method on the customer BillingAddress.
Here is one way to do it:
var fixture = new UnitFixture();
var order1 = fixture.CreateWithAutoMockDependencies<Order>(callBase = true); // If not callbase it won't call the ctor
var order2 = fixture.CreateWithAutoMockDependencies<Order>(callBase = true); // If not callbase it won't call the ctor
fixture.GetAutoMock<Address>(order2, "->customer->billingAddress").Verify(a => a.SetZip("11111")); // If you want only want for order2 and billing
fixture.GetAutoMocks<Address>(order2).Verify(a => a.SetZip("11111")); // To verify for all addresses for order 2
fixture.GetAutoMocks<Address>().Verify(a => a.SetZip("11111")); // To verify for all orders and all addressesOr:
var fixture = new IntegrationFixture(); // IntegrationFixture is better suited for integration testing as it won't mock anything unless specified via the AutoMockTypeControl setting or the class is abstarct/interface
fixture.AutoMockTypeControl.AlwaysAutoMockTypes.Add(typeof(Address));
var order1 = fixture.Create<Order>();
var order2 = fixture.Create<Order>();
// Verify as aboveOr in attribute form (currently supporting NUnit but you need to install the corresponding nuget package)
[NUnit.Framework.Test]
[UnitAutoData] // [UnitAutoData] uses the UnitFixture, while [IntegrationAutoData] uses the IntegrationFixture
public void MyTestMethod([CallBase]Order order1, [CallBase]Order order2, IAutoMockFixture fixture)
{
// Verify as above
}Verifiable)callbase is false (in which case it shouldn't)Mock via late binding (such as generic on the interface) and also calling As<that interface> it will not call the original implementation even if the base is not virtualCallbase = false it does not call any constructors on the objectAutoMock has an implicit cast to the mocked object, in many cases there is no need to call .Object on it####### TODO
TestCaseGenericAttribute and TestCaseSourceGenericAttribute, and for C#11 one can use a generic TestCaseAttribute<>Recursive ctor: Can create recursive object graphs (i.e. if the ctor of Foo requires a Bar that in turn requires Foo), in this case all of them will use the same object
Freeze by attribute on class: Freeze if the type has the Singleton or Scoped DI attribute from our DotNetPowerExtensions framework, note that any frozen object will not be garabage collected while the fixture is in scope
Provide ctor arguments manually: Can inject a particular constructor argument by type or by name via the ConstructorArgumentCustomization customization, and also providing the ability to remove the customization via RemoveCustomization(), (this way multiple calls to Create can have different constructor arguments)
Trace builder: Can use TraceBehavior to trace the builders use to create the objects as well as all builders that have been attempted
Dispose: Can use .Dispose() to automatically to dispose all disposable created objects and disposable customizations
Can register a derived class to replace the original request: Either replace a concrete class with a subclass (via SubClassCustomization or SubClassTransformCustomization) or an open generic class (via SubClassOpenGenericCustomization or SubClassTransformCustomization), can be useful to replace for example DbSet<> with a dervied class for any concrete instance of DbSet<>
NOTE: For SubClassOpenGenericCustomization you should use any generic parameter and it will be ignored
Access object in graph: Provide the ability to access any objects and mocks down the object graph by type (for mocks) or by path, it alos provides the list of paths if needed
CAUTION: Since return values of method calls and some property access might be created lazily then if the path/mock doesn't exist it won't show up
WORKAROUND: For mocks we can freeze the type and then create it directly from the fixture and use it, also GetAutoMocks and GetAutoMock have an overload that does it automatically, as well as For and Object
CAUTION: Freeze won't freeze existing objects, so if writing this workaround directly it should NOT be used if it is already in the mock
Attributes for Moq fixtures: Use the UnitAutoData or IntegrationAutoData attribtues on the method to get passed in a UnitFixture or IntegrationFixture respectively (currently only available for NUnit), will also dispose of the fixture after the test run
Attribute support for fixture customization: Use the UnitAutoData or IntegrationAutoData attribtues also have a generic version that supports passing in an ICustomization to customize the fixture, requires the customization to have a defualt ctor (currently only available for NUnit)
SUT with mock dependecies: Can automatically mock all dependencies including mockable property and field values (as well as all dependencies for non mockable) via the CreateWithAutoMockDependecies call or use UnitFixture (or via attributes when using AutoData to inject the arguments in the test method)
Force Mock: Can specifically demend that an object should be a mock via the CreateAutoMock call (or via attributes when using AutoData to inject the arguments in the test method)
Force Mock by Type: Can specifically demend that an object should be always mocked or not mocked via the AutoMockTypeControl on the fixture or the Create call
List setup: The AutoMock gives a list of methods and properties that have been setup with Moq and also non setup methods/properties and the reason why it hasn't
Can specify specific types that should always be mocked within the object graph (without having the objects frozen)
Setup dependencies: For AutoMock we automatically setup all properties and fields that are mockable to be AutoMock as well as having all methods and out params return AutoMock,Once an AutoMock always an AutoMock (unless you specify via AutoMockTypeControl)
Unique method return: For mocks there is the option to have the methods setup to return unique results per invocation (by passing in MethodSetupTypes.LazyDifferent to the fixture)
Eager vs Lazy: For mocks by default the return value for methods is created when first time called (to optimize the generation of the mock), this can be changed by passing in MethodSetupTypes.Eager to the fixture
Verify fixture: Verify all mocks in the fixture at once
Explicit interface implementation: Sets up explictly implemented interface members when Callbase is false
Can register a derived class to replace the original request: Either replace a concrete class with a subclass (via SubClassCustomization or SubClassTransformCustomization) or an open generic class (via SubClassOpenGenericCustomization or SubClassTransformCustomization), can be useful to replace for example DbSet<> with a dervied class for any concrete instance of DbSet<>
Sets up GetHashCode and .Equals to work correctly even when Callbase is false
Defaults to Callbase = false however for Relay obejcts it sets Callbase = true, but there is an option to pass in the Createxxx calls to change the default for non relays
When Callbase = true it does not setup implemented methods (i.e. not in an interface and the method is not abstract)
####### TODO
ForMock (also it should better remove all readonly warning for it, and disallow newing it up with this constructor, [we might even control it with reflection by restricting getting the type of it... by using our special Stub type])Singleton or Scoped attribute)The main components in Autofixture are as follows:
NoSpeicmen if it is unable to do so, should implement ISpecimenBuilderType object, as well as a PropertyInfo/FieldInfo/ParameterInfo object, or more specific requests such as a SeededRequestfixture.ResidueCollectors listISpecimenBuilderTransformationIRequestSpecification, provides an easy unified way of checking if a request is matching a specific criteriaISpecimenCommandICustomization, or 2) a Builder passed in to the fixture.Customizations listcontext.Resolve(request)) by going through all builders registered and checking for the first one that does not return NoSpecimen (unless OmitSpecimen has been returned)ContextPostprocessorISpecimenBuilder to the fixture.Customizations listResucrsionGuard that controls the recursion level depthnull as it might be a legitimate resultIRecursionHandlerCommand after building, optionally only if the constructed specimen matches a specification
- CAUTION: The specification option on the Processor only determines whether to execute the commands on the specimen and works on the speicmen not the requet, but the specimen is returned regardless of the specification.
In order to prevent the builder from building or the specimen from returing you should use FilteringSpecimenBuilder around the PostprocessorIRequestSpecificationISpecimenBuilder that takes a list of ISpecimenBuilder objects and goes through all the passed in checking for the first one that does not return NoSpecimen (unless OmitSpecimen has been returned)ISpecimenCommand that takes a list of ISpecimenCommand object and executes each of themISpecimenBuilder that always returns the suppleid objectIRequestSpecification that takes a list of IRequestSpecification objects and passes if one of them is satisfiedCreate()) will try to generate the object and mock all dependencies (such as ctor arguments and property/field values)Create()) will not mock any dependencies (such as ctor arguments and property/field values) unless explictly specified or it is impossible to generatere another way (i.e. interfaces/abstract classes)AutoMockRequest/AutoMockDirectRequest/AutoMockDependenciesRequest/NonAutoMockRequestITracker typically by inheriting BaseTrackerIFixtureTracker, typically by inheriting TrackerWithFixtureAutoMock implements IAutoMockRequestITracker tracks the children that it creates, as well as returning a path constructed of it's place in the object graph, as well as references to it's parent and to the start trackerAutoMockT that we want to create an AutoMock<T> for itAutoMock) object (typicaly the SUT object), but have all depedencies and property/field valeus mocked, suitable for unit testingISpecimenContext that keeps track of objects in process of bulding so to be abel to handle recursion