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

C#.NetUnit TestingTdd

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

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 taxDALMock = new Mock(); > 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 taxDALStub = new Mock(); > 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.

Solution 2 - C#

There are at leat 5 different kinds of test doubles: dummies, stubs, mocks, spies and fakes. A good overview is at http://code.google.com/testing/TotT-2008-06-12.pdf and they are also categorized at http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html

Solution 3 - C#

You want to test a chunk of code, right, let's say a method. Your method downloads a file from a http url, and then saves the file on disk, and then mail out that the file is on disk. All these three actions are of course service-classes your method calls, because then they are easy to mock. If you don't mock these, your test will download stuff, access the disk, and mail a message every time you run that test. Then you are not just testing the code in the method, you are also testing the code that downloads, writes to disk and sends a mail. Now if you are mocking these, you are testing just the methods code. Also you are able to simulate a download failure for instance, to see that your method's code is behaving correctly.

Now as for faking, I usually fake classes that are just holding values, and don't have much logic. If you are sending in an object that holds some values, that get changed in the method, you can read off of it in the test to see that the method do the right thing.

Of course the rules can (and sometimes must) be bent a bit, but the general way of thinking is test your code, and your code only.

Solution 4 - C#

The Little Mocker, from Bob Martin, is a very good reading on the topic.

> [...] long ago some very smart people wrote a paper that introduced and defined the term Mock Object. Lots of other people read it and started using that term. Other people, who hadn't read the paper, heard the term and started using it with a broader meaning. They even turned the word into a verb. They'd say, "Let's mock that object out.", or "We've got a lot of mocking to do."

The article explains the differences between mocks, fakes, spys and stubs.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionvijaysylvesterView Question on Stackoverflow
Solution 1 - C#Anderson ImesView Answer on Stackoverflow
Solution 2 - C#Esko LuontolaView Answer on Stackoverflow
Solution 3 - C#crunchdogView Answer on Stackoverflow
Solution 4 - C#Benoit BlanchonView Answer on Stackoverflow