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

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.

Leave a Comment