A simple framework for unit tests using substitutes for dependencies
SubstituteUnitTests aims to reduce the amount of boilerplate code in unit tests.
Consider for example the following code for a unit test using NSubstitute:
[TestMethod]
public void SomeTestMethod()
{
// Arrange
var dependencyA = Substitute.For<IDependencyA>();
// Fake the Work method:
dependencyA.Work().Returns(35);
var dependencyB = Substitute.For<IDependencyB>();
// Additional setup of mocks goes here
var myClass = new MyClass(dependencyA, dependencyB);
// Act and Assert goes here
}
Using SubstituteUnitTests we can reduce the code to:
[TestMethod]
public void SomeTestMethod()
{
// Arrange
var myClass = CreateUnit(setupHelper =>
{
// Fake the Work method:
setupHelper.Get<IDependencyA>().Work().Returns(35);
// Additional setup of mocks goes here
});
// Act and Assert goes here
}
Your test class should inherit from SubstituteUnitTestBase - The T stands for the class we wish to perform the unit test on.
[TestClass]
public class MyClassTests : SubstituteUnitTestBase<MyClass>
{
...
}
T can be any class that has only interfaces in its ctor or none at all.
Now you can call CreateUnit to create the object of the test: This method will find the most relevant Ctor and initialize it by creating substitutes (using NSubstitute) for each interface parameter.
CreateUnit also accepts an Action delegate so you can setup the mocks for your dependencies:
// The class definition:
public class MyClass
{
public MyClass(IDependencyA dependencyA, IDependencyB) {...}
}
// Setup the unit test:
CreateUnit(setupHelper =>
{
// Get ctor parameter by type:
setupHelper.Get<IDependencyA>().Work().Returns(35);
// Get ctor parameter by name:
setupHelper.Get<IDependencyB>("dependencyB").Work().Returns(49);
});
If you don't want to use the default mocks that are generated, you can set your own values:
// Concrete implementation:
var myDependencyA = new DependencyA();
// Some type of mock:
var myDependencyB = Substitute.For<IDependencyB>();
// Setup the unit test:
CreateUnit(setupHelper =>
{
// Set ctor parameter by type:
setupHelper.Set(myDependencyA);
// Set ctor parameter by name:
setupHelper.Set<IDependencyB>("dependencyB");
// Set ctor parameter and use the return value to continue the setup:
setupHelper.Set<IDependencyB>("dependencyB").Work().Returns(49);
});