Dummy, Fake, Stub, Mock, Spy
////////// Dummy
// It’s a placeholder required to pass the unit test.
[TestMethod]
public void PlayerRollDieWithMaxFaceValueStrictTest()
{
var dummyBoard = new Mock<IBoard>(MockBehavior.Strict); //Ensure Board class is never invoked
var player = new Player( dummyBoard.Object, new Die() );
player.RollDie();
Assert.AreEqual( 6, player.UnitsToMove );
}
////////// Fake
// Simplify a dependency so that unit test can pass easily.
public interface IProductRepository
{
void AddProduct(IProduct product);
IProduct GetProduct(int productId);
}
public class FakeProductRepository : IProductRepository
{
List<IProduct> _products = new List<IProduct>();
public void AddProduct(IProduct product)
{ }
public IProduct GetProduct(int productId)
{ }
}
[TestMethod]
public void BillingManagerCalcuateTax()
{
var fakeProductRepository = new FakeProductRepository();
BillingManager billingManager = new BillingManager(fakeProductRepository);
//...
}
////////// Stub
// Provide indirect inputs to the SUT coming from its collaborators / dependencies.
// The following example: use a Stub to return a fixed face value. This could simply our tests by taking out the randomness associated with rolling a Die.
[TestMethod]
public void PlayerRollDieWithMaxFaceValue()
{
var stubDie = new Mock<IDie>();
stubDie.Setup(d => d.GetFaceValue()).Returns(6).Verifiable();
IDie die = stubDie.Object;
Assert.AreEqual(6, die.GetFaceValue()); //Excercise the return value
}
////////// Mock
// For behavior verification. We can set expectations for SUT to exhibit the right behavior during its interactions with collaborators. Classic example of this is logging.
[TestMethod]
public void ModuleThrowExceptionInvokesLogger()
{
var mock = new Mock<ILogger>();
Module module = new Module();
ILogger logger = mock.Object;
module.SetLogger(logger);
module.ThrowException("Catch me if you can");
mock.Verify( m => m.Log( "Catch me if you can" ) );
}
////////// Spy
// A variation of behavior verification. Instead of setting up behavior expectations, Spy records calls made to the collaborator.
[TestMethod]
public void ModuleThrowExceptionInvokesLoggerOnlyOnce()
{
var spyLogger = new Mock<ILogger>();
Module module = new Module();
ILogger logger = spyLogger.Object;
module.SetLogger( logger );
module.ThrowException( "Catch me if you can" );
module.ThrowException( "Catch me if you can" );
spyLogger.Verify( m => m.Log( It.IsAny<string>()), Times.Exactly(2) );
}
Other references: martinflower.com: mock aren't stubs.