When to use mocking versus faking in C# unit testing?

vijaysylvester picture vijaysylvester · Sep 14, 2009 · Viewed 15.4k times · Source

Can anyone come up with guidelines suggesting the ideal scenarios to choose mocking versus faking, i.e., setting up the essentials manually?

I am a bit confused with how to approach this situation.

Answer

Anderson Imes picture Anderson Imes · Sep 14, 2009

Well you have a few things you need to sort out. You have two basic things you'll need to know: Nomenclature and Best Practices.

First I want to give you a great video resource from a great tester, Roy Osherove:

Unit Testing Reviews by Roy Osherove

He starts out by saying that he has done some reviews of test harnesses shipped with several open source projects. You can find those here: http://weblogs.asp.net/rosherove/archive/tags/TestReview/default.aspx

These are basically video reviews where he walks you through these test harnesses and tells you what is good and what is bad. Very helpful.

Roy also has a book that I understand is very good.

Nomenclature

This podcast will help out immensely: http://www.hanselminutes.com/default.aspx?showID=187

I'll paraphrase the podcast, though (that Hanselminutes intro music is dreadful):

Basically everything you do with an isolation framework (like Moq, Rhino Mocks, Type Mock, etc) is called a fake.

A fake is an object in use during a test that the code you are testing can call in place of production code. A fake is used to isolate the code you are trying to test from other parts of your application.

There are (mainly) two types of fakes: stubs and mocks.

A mock is a fake that you put in place so that the code you are testing can call out to it and you assert that the call was made with the correct parameters. The below sample does just this using the Moq isolation framework:

[TestMethod]
public void CalculateTax_ValidTaxRate_DALCallIsCorrect()
{
    //Arrange
    Mock<ITaxRateDataAccess> taxDALMock = new Mock<ITaxRateDataAccess>();
    taxDALMock.Setup(taxDAL => taxDAL.GetTaxRateForZipCode("75001"))
                  .Returns(0.08).Verifiable();

    TaxCalculator calc = new TaxCalculator(taxDALMock.Object);

    //Act
    decimal result = calc.CalculateTax("75001", 100.00);

    //Assert
    taxDALMock.VerifyAll();
}

A stub is almost the same as a mock, except that you put it in place to make sure the code you are testing gets back consistent data from its call (for instance, if your code calls a data access layer, a stub would return back fake data), but you don’t assert against the stub itself. That is, you don’t care to verify that the method called your fake data access layer – you are trying to test something else. You provide the stub to get the method you are trying to test to work in isolation.

Here’s an example with a stub:

[TestMethod]
public void CalculateTax_ValidTaxRate_TaxValueIsCorrect()
{    
    //Arrange
    Mock<ITaxRateDataAccess> taxDALStub = new Mock<ITaxRateDataAccess>();
    taxDALStub.Setup(taxDAL => taxDAL.GetTaxRateForZipCode("75001"))
                  .Returns(0.08);

    TaxCalculator calc = new TaxCalculator(taxDALStub.Object); 

    //Act
    decimal result = calc.CalculateTax("75001", 100.00);

    //Assert
    Assert.AreEqual(result, 8.00);
}

Notice here that we are testing the output of the method, rather than the fact that the method made a call to another resource.

Moq doesn’t really make an API distinction between a mock and a stub (notice both were declared as Mock<T>), but the usage here is important in determining the type.

Hope this helps set you straight.