A source generator that automatically creates mocks for a unit test class. This generator is for integration with MSTest projects.
$ dotnet add package SlowFox.UnitTestMocks.MSTestSlowFox is a suite of .NET source generators, aiming to reduce the amount of repetitive code you need to write and maintain.
Source generators incur no run-time cost (as no reflection is involved), because the code is created at build time. Plus, using a supported IDE (like Visual Studio 2019/2022), you can see what's being generated immediately when you save your source code.
There are currently 2 generators available via SlowFox:
SlowFox.UnitTestMocks is a generator that creates mock objects (using Moq) for the dependencies of a class that is to be tested.
Firstly, choose and install the NuGet package relating to your testing framework:
Next, create a new test class, mark it as partial and apply the InjectMocks attribute, indicating the class that you're going to be tested:
namespace MySampleProject
{
[TestClass]
[SlowFox.InjectMocks(typeof(UserHandler))]
public partial class UserHandlerTests
{
}
}SlowFox will then generate mock objects for each dependency of the selected class, and provide a Create method that instantiates a new instance of the selected class with the mock objects used as dependencies:
namespace MySampleProject
{
public partial class UserHandlerTests
{
private Mock<IDatabase> _database;
private Mock<ILogger> _logger;
[TestInitialize]
public void Init()
{
_database = new Mock<IDatabase>(MockBehavior.Strict);
_logger = new Mock<ILogger>(MockBehavior.Strict);
}
private UserHandler Create()
{
return new UserHandler(_database.Object, _logger.Object);
}
}
}You can call Create() in your tests to get the object to test, and you can reference the mock objects to set up any pre-defined responses, or to perform validation:
namespace MySampleProject
{
[TestClass]
[SlowFox.InjectMocks(typeof(UserHandler))]
public partial class UserHandlerTests
{
[TestMethod]
public void VerifyAddUser()
{
_database
.Setup(p => p.Save(It.IsAny<User>()));
UserHandler reader = Create();
reader.CreateNewUser();
_database
.Verify(p => p.Save(It.IsAny<User>()), Times.Once);
}
}
}You are able to exclude specific types from being mocked, by using the ExcludeMocks attribute. Any type specified within this attribute will be added as a parameter on the Create method, so you can provide a value from within your test:
namespace MySampleProject
{
[TestClass]
[SlowFox.InjectMocks(typeof(UserHandler))]
[SlowFox.ExcludeMocks(typeof(ILogger))]
public partial class UserHandlerTests
{
[TestMethod]
public void VerifyAddUser()
{
_database
.Setup(p => p.Save(It.IsAny<User>()));
ILogger testLogger = BuildTestLogger();
UserHandler reader = Create(testLogger);
reader.CreateNewUser();
_database
.Verify(p => p.Save(It.IsAny<User>()), Times.Once);
}
}
}Note that types that cannot be mocked (e.g., a static or sealed type) will automatically be excluded from being mocked, and will be treated in the same way as types specified in the
ExcludeMocksattribute
This generator is compatible with constructors that have been generated using SlowFox.Constructors.
Configuration is set in a .editorconfig file.
To configure the generated code to not use underscores for member names, set the skip_underscores value to true:
[*.cs]
slowfox_generation.unit_test_mocks.mstest.skip_underscores = true
To create the mocks using the Loose behaviour (instead of the default of Strict), set the use_loose value to be true:
[*.cs]
slowfox_generation.unit_test_mocks.mstest.use_loose = true