Saturday, May 5, 2012


Introduction to Mocks and Stubs


Mock objects are simulated objects that mimic the behavior of real objects in controlled ways. We typically create mock objects to test the behavior of some other object.

A stub is a replacement for an existing dependency in the system. By using a stub, you can test your code without dealing with the dependency directly.

Consider a scenario where you need mocks and stubs

    You want to simulate the behavior of the dependent objects, say you wish to mock and test EmailSender. While testing such things we won’t be really connecting to Email server. In this scenario, we can simply mock and test the behavior of email sender and verify the expectations set against the mock object.

    Imagine you are testing a data access class which connects to DB fetches, inserts / updates some data. We can make use of mock and stub techniques to test the DAO logics without the database dependency.

Why Mocking?

If you are planning to isolate the dependencies of an object and unit test, then you will have to mock and test.

Here I'm considering an example of User object which has SendEmail method used to send an email with subject, body and email address.

public class User
{
    public FirstName { get; set; }
    public LastName { get; set; }
    public UserName { get; set;}
    public Password { get; set; }
    public Email { get; set; }       
    public User() { }
    public bool SendEmail(IEmailSender emailSender)  {
        string subject = "Your Password";
        string body = String.Format("{0} {1}, your password is {2}", FirstName,  LastName, Password);
        return emailSender.Send(subject, body, Email);
    }
}

You will notice one thing here the User object depends on the instance of IEmailSender type to send mail for the specified user email address.


public interface IEmailSender
{
   bool Send(string subject, string body, string email);  
}

We will learn how we can mock the EmailSender and test the expected behavior.

The below example is making use of Moq Framework for mock and unit testing

[Test]
public void User_Can_Send_Email()
{
        var emailMock = new Moq.Mock<IEmailSender>();
        emailMock
             .Expect(sender => sender.Send(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
             .Returns(true);        
          User user = new User();
          Assert.That(user.SendEmail(emailMock.Object) == true);
}

The unit tests creates a mock object of type IEmailSender and sets the expectation for Send method with any arguments passed as a parameter to it should return ‘true’.

At the ends of the unit test, we did an assertion for the user.SendMail to verify for the true value. You can also add a .Verifiable() on the end of the mock setup code and then call emailMock.Verify() after you run your test code and verify that the method was actually called.

An Example for a Stubbed Class

public class StubbedSecurityDataStore : ISecurityDataStore
{
    public bool Authenticate(string userName, string password)
    {
        return true;
    }
    public string[] GetRoles(string userName)
    {
       return new string[]{“Admin”, “Write”, “Read”};
    }
}

About Moq Framework

Moq is an open source framework and has adopted an API that tries to be both simple to learn and easy to use. The API also follows the arrange-act-assert style and relies heavily on .NET 3.5 features, such as lambdas and extension methods. The learning curve is quite easy, but you need to feel comfortable with using lambdas. 

Difference between Mock and Stubs

Mock objects are used to define expectations i.e. we expect some methods to be called with such and such parameters. Mocks record and verify such expectations.

Stubs, on the other hand have a different purpose: they do not record or verify expectations, but rather allow us to provide “fake” objects in order to utilize a test scenario. Stubbing a method is all about replacing the method with code that returns a specified result. Most important thing is a stub will never cause a test to fail.

2 comments:

  1. Stubs are basically used to provide data while Moq is to Substitute the behaviors. Superbly explained... hats off..

    ReplyDelete
  2. Thanks Satish venkatakrishnan.. I would also suggest peoples with an article from Martin Fowler about "Mocks Are'nt Stubs" http://martinfowler.com/articles/mocksArentStubs.html

    ReplyDelete