Archive | mocking RSS feed for this section

Getting Started With Mocking – Part 2- Using MOQ

2 Apr

Download Code

This is the second part of the 2 post series on Mocking. In the last post, we discussed the basics of Mocking and how Adam (the intern) used Manual Mocking to unit test the simple Shopping Cart application he’s building. In this post, we’ll see how using a Mocking library can make the process of mocking out dependencies simpler.

Why use a mocking library?
The projects you work on are usually nowhere as simple/small as the Shopping Cart example Adam is working on (If they are, is there room for one more on the team?). If you have to build a new mock class for each of your classes, the amount of new code you have to write increases significantly. Also, you might want to reuse your test infrastructure across different classes, or just want the mock object to act dumb.

It’s also harder to do interaction based testing using Manual Mocks. In the manual mock for Logger, we had to add a new field to track how many times it is called. As the behavior to test becomes complicated, so does your mock class. Using a mocking library can take care of all these mundane things.

 Why MOQ?
MOQ is a simple and easy to learn mocking library for .NET that takes advantage of .NET 3.5 (i.e. Linq expression trees) and C# 3.0 features (i.e. lambda expressions). There are other mocking libraries like RhinoMocks and TypeMock Isolator, and MOQ is relatively new to the scene. The main reason I recommend using MOQ is because it has a really low learning curve and is intuitive to use. Unlike other libraries, it does not force you to distinguish between a mock and a stub, which makes it easier for developers new to mocking to work with.

MOQ Basics
To create a mock of type T, you will use the Mock<T> class. Any interface type can be used for mocking, but for classes, only abstract and virtual members can be mocked. Let’s walk through a few common scenarios and the corresponding MOQ usage.

Creating Mock objects

 Mock<IProduct> _mockProduct = new Mock<IProduct>();
 Mock<ILogger> _mockLogger = new Mock<ILogger>();

Mocking a method implementation and returning fake data

 _mockProduct.Setup(m => m.GetProductCategory()).Returns("Test Category");

Mocking a property and returning fake data

_mockProduct.SetupGet(m => m.Name)
            .Returns("Product 1");

Throw exception

 _mockLogger.Setup(m => m.Log(It.Is<string>(p => p == null)))
            .Throws(new ArgumentNullException());

Validate Parameters

 _mockLogger.Setup(m => m.Log(It.IsRegex("[1-9]+")))
            .Callback(() => Console.WriteLine("Numbers passed"));

Verify Interactions

 _mockLogger.Object.Log("test");
 _mockLogger.Verify(m => m.Log(It.Is<string>(s=>s=="test")),Times.Once());

Invoke Callback

 int counter = 0;
 _mockLogger.Setup(m => m.Log(It.IsAny<String>())).Callback(() => counter++);

Even if you are new to MOQ, you’ll find the API very intuitive and easy to pick up.

Back to the Shopping Cart

So Adam sees how easy it is easy to work with MOQ and how much code/effort it saves him, and he updates his unit tests for the Shopping Cart accordingly. Note that these unit tests are independent of the manual mock classes as well as from external resources like the filesystem/database.

   1:  [TestMethod]
   2:  public void AddProduct_AddingProductWithPrice10_ShouldMakeTotal10()
   3:  {
   4:      var mock = new Mock<IProduct>();
   5:      mock.SetupGet(m => m.Price).Returns(10.00M);
   6:      var cart = new ShoppingCart(null);
   7:      cart.AddProduct(mock.Object);
   8:      Assert.AreEqual(10.00M, cart.Total);
   9:   
  10:  }
  11:   
  12:  [TestMethod]
  13:  public void AddProduct_AddingProduct_ShouldCallLogger()
  14:  {
  15:      var mockProduct = new Mock<IProduct>();
  16:      var mockLogger = new Mock<ILogger>();
  17:      mockLogger.Setup(m => m.Log(It.IsAny<string>())).Verifiable("Log should have been called");
  18:      var cart = new ShoppingCart(mockLogger.Object);
  19:      cart.AddProduct(mockProduct.Object);
  20:      mockLogger.Verify();
  21:  }

Later….

You are satisfied with the ShoppingCart project and the corresponding tests that Adam built. When you run into him in the evening, you commend him on the nice work and invite him to have a couple of beers with you. As you are sitting at the bar, you glance at the mirror and you see something that makes the hair at the back of your neck stand up. Instead of Adam and you at the bar, it’s just you sitting there with 2 beers in your hand talking to yourself. You then realize that Adam was a figment of your imagination and you might have suffered from some sort of a dual personality disorder (Kind of like Fight Club). Your brain created Adam so that you could face your fears and misconceptions about Unit Testing and Mocking. On the bright side, you realize that you have finished your project and are sitting in a bar with 2 beers. Cheers!

Download Code

Getting Started with Mocking – Part 1 – The Basics

10 Feb

Download Code.

This 2 part blog post series is based on a talk I gave at the Dallas C# SIG last month. In this post, I describe general mocking concepts that are independent of mocking frameworks. In the next post, I’ll describe how using a mocking framework (like MOQ) can reduce development time and effort.

You are probably familiar with Unit Tests, but let’s spend a little time revisiting them. As per Roy Osherove 
              “A unit test is a fast, in-memory, consistent, automated and repeatable test of a functional unit-of-work in the system.”
This is different from writing Integration Tests, which can talk to external resources such as the filesystem, webservices, database and are inherently slow. A common mistake is to create a Unit Test Suite but fill it with Integration tests. This increases the test execution time and discourages developers from running the Unit Tests on a regular basis (Ideally, each time before checking in code or more frequently).

For the purpose of this series, lets assume that you are a senior developer at a firm with plenty of work on your hands. Your pointy haired manager stops by to tell you that he has a new project for you. Seeing that you are busy, he offers to assign you an intern, Adam. You reluctantly agree and talk to Adam who seems like a sharp, reserved guy with a good grasp over OOPs concepts. You go over the project requirements with him, which consist of building a simple Shopping Cart. The Shopping Cart should

  1. have the capability to add a product and update price accordingly,
  2. have some sort of logging functionality.

Adam seems confident that he can build this project, When asked about Unit Testing, he admits not having any prior experience with it. You tell him to look it up, and write Unit Tests for his code as well. So Adam goes into his cave, and starts working on the Shopping Cart app.He informs you after 2 days that he has now completed the application and his code is ready for review. The basic design looks like this

MOQ_ClassDiagram[1]

The code for the ShoppingCart class is pretty simple. It has a Total property denoting the total price of the Shopping Cart, and an AddProduct() function, which adds the price of the product to the total and logs a message. The logger object is passed to the ShoppingCart via constructor injection. Also, the ShoppingCart is coded against IProduct and ILogger interfaces rather than concrete implementations, which makes testing easier.

   1:   public class ShoppingCart
   2:      {
   3:          public ShoppingCart(ILogger logger)
   4:          {
   5:              this._logger = logger;
   6:          }
   7:   
   8:          private ILogger _logger;
   9:          public decimal Total { get; set; }
  10:   
  11:          public void AddProduct(IProduct product)
  12:          {
  13:              Total = Total + product.Price;
  14:              if (_logger != null)
  15:                  _logger.Log(String.Format("Product {0} has been added.",product.Name));
  16:          }
  17:      }

We don’t really care about the Logger and Product implementation, but just know that the Logger logs to a text file in “C:\temp”, and the Product class retrieves the product’s price from the database. Adam has created 2 unit tests, one to check that the Shopping Cart updates its price correctly, and the second one to ensure that logging is done.

   1:          [TestMethod]
   2:          public void AddProduct_AddingProductWithPrice10_ShouldMakeTotal10()
   3:          {
   4:              var target = new ShoppingCart(null);
   5:              //make sure product with ID =1 in database has Price = 10.00
   6:              var product = new Product {ID = 1, Name = "Product1"};
   7:              target.AddProduct(product);
   8:              Assert.AreEqual(target.Total, 10.00M);
   9:          }
  10:   
  11:          [TestMethod]
  12:          public void AddProduct_AddingProduct_ShouldCallLogger()
  13:          {
  14:              var logger = new Logger();
  15:              var target = new ShoppingCart(logger);
  16:              var product = new Product {ID = 2, Name = "Product2"};
  17:              target.AddProduct(product);
  18:              //Open log file and make sure corresponding log was added.
  19:          }

Clearly, his Unit Tests leave a lot to be desired. They depend on the state of the database and the filesystem and therefore are not fast or in-memory. For the same reasons, they are also not repeatable or automated. These are in fact, more close to Integration Tests than Unit Tests. This is a very common mistake. You advise him to mock his dependencies, and since the ShoppingCart class interacts with interfaces rather than concrete implementations, this should be easy to accomplish.

Stubs VS Mocks

The definition of stubs and mocks and their differences has been debated many times before. The Mocks Aren’t Stubs article by Martin Fowler is a good resource to get started (The concepts really hit home for me after reading Roy Osherove’s The Art of Unit Testing. I highly recommend the book if you are getting started with Unit Testing). A few guidelines to remember about Mocks and Stubs are:

  • You can have many stubs in a unit test, but you should have only one mock object.
  • Stubs help in getting the unit test set up, but you’ll never assert against the stub object. You’ll assert against the class under test. 

stub[1]

If you are using mocks, you will assert against the mock object. Stubs lend themselves more naturally to state based unit testing and mocks to interaction based unit testing.

mock[1]

Adam now understands what he is doing wrong, and works on isolating his unit tests to test only the ShoppingCart class. He creates new implementations for IProduct and ILogger that he can use for Unit Testing. Note that in the new implementations, he only has to put in logic needed to get his unit tests to work.

   1:      public class ProductStub:IProduct
   2:      {
   3:          public string Name { get; set; }
   4:          public decimal Price { get; set; }
   5:          public string GetProductCategory()
   6:          {
   7:              throw new NotImplementedException();
   8:          }
   9:      }
  10:      public class LoggerMock:ILogger
  11:      {
  12:          public int NumberOfTimesLoggerCalled { get; set; }
  13:          public void Log(string text)
  14:          {
  15:              NumberOfTimesLoggerCalled++;
  16:          }
  17:      }

And he revises his Unit Tests accordingly

   1:          [TestMethod]
   2:          public void AddProduct_AddingProductWithPrice10_ShouldMakeTotal10()
   3:          {
   4:              var cart = new ShoppingCart(null);
   5:              var stubProduct = new ProductStub(){Price=10.00M};
   6:              cart.AddProduct(stubProduct);
   7:              Assert.AreEqual(cart.Total, 10.00M);
   8:          }
   9:   
  10:          [TestMethod]
  11:          public void AddProduct_AddingProduct_ShouldCallLogger()
  12:          {
  13:              var loggerMock = new LoggerMock();
  14:              var cart = new ShoppingCart(loggerMock);
  15:              int oldNumberOfTimes = loggerMock.NumberOfTimesLoggerCalled;
  16:              cart.AddProduct(new ProductStub());
  17:              Assert.AreEqual(oldNumberOfTimes + 1, loggerMock.NumberOfTimesLoggerCalled);
  18:          }

Adam’s Unit Tests now pass and he has done a good job of keeping them free from external resources such as the filesystem or database by manually mocking his classes. Note how the first Unit Test uses the new IProduct implementation (a Stub) to support the Unit Test but asserts against the Shopping Cart object, whereas the second one asserts against the new ILogger implementation (a Mock).

In the next post, we’ll see how Adam can achieve the same granularity in his Unit Tests by using a mocking framework rather than creating manual mocks.

Download Code.

Part 2.


Rss Feed Tweeter button Facebook button