Wednesday, March 5, 2014

What, when, how - dummy, fake, stub and mocks

Test doubles are objects that replace the
dependent-on-component (DOC) in a test context so that the system under test
gets an API as the real DOC and can perform activities against the API thinking
that it is a real one!!!

In this post I’ll demonstrate the usage of the four main
test doubles (Dummy, Fake, Stub and Mock) in the context of Microsoft Fakes and
scenarios on how they can be implemented in your projects to enhance code
coverage. All the definitions for the patterns are copied from Gerard MeszarosXUnitPatterns catalog.

Dummy: A dummy is an
object that is passed as a method argument or used as an attribute in a test
context but never actually used. Usually they are just used to fill parameter
lists.

var dummyCustomer = newStubCustomer();

var sut = newInvoice(dummyCustomer);

var book = newProduct("XUnitPatterns");

sut.AddItemQuantity(book,
5);

var actual = sut.GetAllLineItems();

Assert.IsTrue(actual.Count() == 1);

Fake: A Fake object
actually have working implementations, but usually take some shortcut which
makes them not suitable for production. The fake object need not have any of
the "-ilities" that the real DOC needs to have (such as scalability);
it need only provide the equivalent services to the SUT so that the SUT isn't
aware it isn't using the real DOC.

var dummyCustomer = newStubCustomer();

var sut = newInvoice(dummyCustomer);

var logger = newFakeLogger();

sut.Logger
= logger;

var book = newProduct("XUnitPatterns");

sut.AddItemQuantity(book,
0); //Throws exception if
quantity is less than 0 and logs the error. Should use the FakeLogger to write
the message to log.

Stub: Stubs can
replace a real object with a test-specific object that feeds the desired
indirect inputs into the system under test. Stubs may also record information
about calls, such as an email gateway stub that remembers the messages it
'sent', or maybe only how many messages it 'sent'.

var dummyCustomer = newStubCustomer();

var sut = newInvoice(dummyCustomer);

var validator = newStubIProductValidator()

{

IsValidProduct = (p) => { returntrue; }

};

sut.Validator
= validator;

var book = newProduct("XUnitPatterns");

sut.AddItemQuantity(book,
2);

var actual = sut.GetAllLineItems();

Assert.IsTrue(actual.Count() == 1);

Mock: A mock replaces
an object the system under test (SUT) depends on with a test-specific object
that verifies it is being used correctly by the SUT. Mocks insist upon behavior
verification. The other doubles can, and usually do, use state verification.
Developers perform assertions on mock objects to ensure that the behavior
expectations were met during test execution