Niraj Bhatt – Architect's Blog

Ruminations on .NET, Architecture & Design

Category Archives: Unit Testing

Dependency Inversion, Dependency Injection, DI Containers and Service Locator

Here is a post I have been planning to do for years :) . Yes, I am talking about Dependency Injection, which by this time, has most likely made its way into your code base. I got to recollect few thoughts around it in a recent discussion and hence writing them down.

Dependencies are the common norm of object oriented programming, helping us to adhere to software principles like Single Responsibility, Encapsulation, etc. Instead of establishing dependencies using direct references between classes or components, they are better managed through an abstraction. Most of the GOF patterns are based around this principle which is commonly referred as ‘Dependency Inversion’. Using Dependency inversion principle we can create flexible Object Oriented designs, making our code base reusable and maintainable.

To further enhance value proposition of the dependency inversion, you can pass the dependencies via a constructor or a property from the root of your application, instead of instantiating them within your class. This would allow you to mock / stub your dependency and make your code easily testable (read unit testing).

E.g.

IA ob = new A(); //Direct instantiation
public D (IA ob) { … } //constructor injection
public IA ob { get; set } //property injection – create object and set the property

Entire software industry sees value in above approach and most people refer to this entire structure (pattern) as Dependency Injection. But beyond this things get little murkier.

Confusion starts for programmers who see above as a standard way of programming. To them Dependency Injection (DI) is the automated way of injecting dependencies using a DI container (DI container at times is also referred as IoC (Inversion of Control) container. As Martin Fowler points out in his classic article, IoC is a generic term used in quite a few cases – e.g. the callback approach of Win32 programming model. In order to avoid confusion and keep this approach discernible, the term DI was coined. In this case, IoC refers to inversion of dependencies creation, which are created outside of the dependent class and then injected.) If you are surprised by this statement, let me tell you 90% of people who have walked to me to ask if I was using DI, wanted to know the about the DI container and my experience with it.

So what the heck is this ‘DI container’? A DI container is a framework which can identify constructor arguments or properties on the objects being created and automatically inject them as part of object creation. Coming from the .NET world, the containers I use include StructureMap, Autofac and Unity. DI containers can be wired up using few lines of code at the starting of your program or you can even specify configuration in a XML file. Beyond that, containers are transparent to the rest of your code base. Most containers also provide AOP (Aspect Oriented Programming) functionality and its variants. This allows you to bundle cross cutting concerns like database transactions, logging, caching, etc. as aspects and avoid boilerplate code throughout the system (I have written a CodeProject article on those lines). Before you feel I am over simplifying things, let me state if you haven’t worked with DI containers in past you are likely to be faced with a learning curve. As is the case with most of the other frameworks, a pilot is strongly recommended. As a side note, the preferred injection rule is – unless your constructor requires too many parameters (ensure you haven’t violated SRP), you should resort to constructor injection and avoid property injection (see fowler’s article for a detailed comparison between the two injection types).

Finally, let’s talk about Service Locator an alternative to DI. A Service Locator holds all the services (dependencies) required by your system (in code or using a configuration file) and returns a specific service instance on request. Service Locator can come in handy for scenarios where DI container is not compatible with a given framework (e.g. WCF, ASP.NET Web APIs) or you want more control over the object creation (e.g. create the object late in the cycle). While you can mock service locator, mocking it would be little cumbersome when compared to DI. Service Locator is generally seen as an anti-pattern in DI world. Interestingly, most DI containers offer APIs which can allow us to use them as Service Locator (lookup for Resolve / GetInstance methods on the container).

Below sample shows you StructureMap – a DI container, in action (use NuGet to add StructureMap dependency).

class Program
{
static void Main(string[] args)
{
var container = new Container(registry =>
{
registry.Scan(x =>
{
x.TheCallingAssembly();
x.WithDefaultConventions();
});
});
var ob = container.GetInstance<DependentClass>();
ob.CallDummy();
}
}

public interface IDependency
{
void Dummy();
}

public class Dependency : IDependency
{
public void Dummy()
{
Console.WriteLine("Hi There!");
}
}

public class DependentClass
{
private readonly IDependency _dep;
public DependentClass(IDependency ob)
{
_dep = ob;
}
public void CallDummy()
{
_dep.Dummy();
}
}

I will try to post some subtle issues around DI containers in future. I hope above helps anyone looking for a quick start on DI and associated terms :) .

Dummy vs. Stub vs. Spy vs. Fake vs. Mock

One of the fundamental requirements of making Unit testing work is isolation. Isolation is hard in real world as there are always dependencies (collaborators) across the system. That’s where concept of something generically called ‘Test Double’ comes into picture. A ‘Double’ allow us to break the original dependency, helping isolate the unit (or System Under Test (SUT) – as commonly referred). As this Double is used to pass a unit test it’s generally referred to as ‘Test Double’. There are variations in types of Test Doubles depending on their intent (reminds me of GOF’s Proxy pattern).

Test doubles are not only useful in state verification but also in behavior verification; help us enhance the code coverage of our unit tests. While demarcating various test doubles may not provide exceptional value add, knowing about them can definitely organize our thinking process around unit testing.  Interestingly Mock Frameworks available today, allow us to seamlessly create all the variations of test doubles. I would be using moq for this blog post. The variations of Test Doubles described below are taken from xUnit Patterns.com. Below are the various test doubles along with examples:

a) Dummy is simple of all. It’s a placeholder required to pass the unit test. Unit in the context (SUT) doesn’t exercise this placeholder. Dummy can be something as simple as passing ‘null’ or a void implementation with exceptions to ensure it’s never leveraged.

[TestMethod]
public void PlayerRollDieWithMaxFaceValue()
{
var dummyBoard = new Mock<IBoard>();
var player = new Player(dummyBoard.Object, new Die() ); //null too would have been just fine
player.RollDie();
Assert.AreEqual(6, player.UnitsToMove);
}

While the above test would work just fine, it won’t throw any exceptions if RollDie implementation is invoking Board Object. To ensure that Board object isn’t exercised at  all you can leverage strict mock. Strict Mock with throw an exception if no expectation is set for member.

[TestMethod]
public void PlayerRollDieWithMaxFaceValueStrictTest()
{
var dummyBoard = new Mock<IBoard>(MockBehavior.Strict); //Ensure Board class is never invoked
var player = new Player( dummyBoard.Object, new Die() );
player.RollDie();
Assert.AreEqual( 6, player.UnitsToMove );
}

b) Fake is used to simplify a dependency so that unit test can pass easily. There is very thin line between Fake and Stub which is best described here as – “a Test Stub acts as a control point to inject indirect inputs into the SUT the Fake Object does not. It merely provides a way for the interactions to occur in a self-consistent manner. These interactions (between the SUT and the Fake Object) will typically be many and the values passed in as arguments of earlier method calls will often be returned as results of later method calls“. A common place where you would use fake is database access. Below sample shows the same by creating a FakeProductRepository instead of using live database.

public interface IProductRepository
{
void AddProduct(IProduct product);
IProduct GetProduct(int productId);
}

public class FakeProductRepository : IProductRepository
{
List<IProduct>
_products = new List<IProduct>();
public void AddProduct(IProduct product)
{
//...
}
public IProduct GetProduct(int productId)
{
//...
}
}

[TestMethod]
public void BillingManagerCalcuateTax()
{
var fakeProductRepository = new FakeProductRepository();
BillingManager billingManager = new BillingManager(fakeProductRepository);
//...
}

Fakes can be also be implemented by moq using callbacks.

c) Stub is used to provide indirect inputs to the SUT coming from its collaborators / dependencies. These inputs could be in form of objects, exceptions or primitive values. Unlike Fake, stubs are exercised by SUT. Going back to the Die example, we can use a Stub to return a fixed face value. This could simply our tests by taking out the randomness associated with rolling a Die.

[TestMethod]
public void PlayerRollDieWithMaxFaceValue()
{
var stubDie = new Mock<IDie>();
stubDie.Setup(d => d.GetFaceValue()).Returns(6).Verifiable();
IDie die = stubDie.Object;
Assert.AreEqual(6, die.GetFaceValue()); //Excercise the return value
}

d) Mock – Like Indirect Inputs that flow back to SUT from its collaborators, there are also Indirect Outputs. Indirect outputs are tricky to test as they don’t return to SUT and are encapsulated by collaborator. Hence it becomes quite difficult to assert on them from a SUT standpoint. This is where behavior verification kicks in. Using behavior verification we can set expectations for SUT to exhibit the right behavior during its interactions with collaborators. Classic example of this is logging. When a SUT invokes logger it might quite difficult for us to assert on the actual log store (file, database, etc.). But what we can do is assert that logger is invoked by SUT. Below is an example that shows a typical mock in action

[TestMethod]
public void ModuleThrowExceptionInvokesLogger()
{
var mock = new Mock<ILogger>();
Module module = new Module();
ILogger logger = mock.Object;
module.SetLogger(logger);
module.ThrowException("Catch me if you can");
mock.Verify( m => m.Log( "Catch me if you can" ) );
}

e) Spy – Spy is a variation of behavior verification. Instead of setting up behavior expectations, Spy records calls made to the collaborator. SUT then can later assert the recordings of Spy. Below is variation of Logger shown for Mock. Focus on this test is to count the number of times Log is invoked on Logger. It’s doesn’t care about the inputs passed to Log, it just records the Log calls and asserts them. Complex Spy objects can also leverage callback features of moq framework.

[TestMethod]
public void ModuleThrowExceptionInvokesLoggerOnlyOnce()
{
var spyLogger = new Mock<ILogger>();
Module module = new Module();
ILogger logger = spyLogger.Object;
module.SetLogger( logger );
module.ThrowException( "Catch me if you can" );
module.ThrowException( "Catch me if you can" );
spyLogger.Verify( m => m.Log( It.IsAny<string>()), Times.Exactly(2) );
}

Hope this helps!!!

Rhino Mocks Training Content

I tried searching on this for a personal assignment but couldn’t locate one. So decided to create it myself. Hope you find it useful. Let me know if your UG needs a session on this :) .

RHINO MOCKS
1 Day Session
Software Requirements: VS.NET 2008 with SP1, Rhino Mocks 3.5, SQL SERVER 2005 / 2008, Windows XP / Vista

Design Principles
      Dependency Injection
      Aspect Oriented Programming
      TDD Development

Mocks
      Introduction to Mocks
      Unit Testing with Mocks
      Types of Mocks
            Dummy
            Fake
            Stubs
            Mocks
      State Verification vs. Behavior Verification
      TDD vs. BDD

Rhino Mocks
      Introduction to Rhino Mocks
      Record / Replay model
      Mock Types
            Strict Mocks
            Dynamic Mocks
            Partial Mocks
      Expectations and Setup
      Methods
      Out Ref Parameters
      Events
      Recursive Mocking
      Ordered / Unordered Expectations
      Call Repetition
      Argument Constraints
      Demos

Unit Testing Links

I have been using Unit Testing for quite some time now. So I thought to collect some good links on it, for anybody who is about to embark this journey.

One such link is this, which does a nice differentiation between unit testing, integration testing & system testing.

Another awesome article is here and a small follow up on it.

I am not sure if I should include this one, here, but i will do it just to indicate the importance of unit testing.

This one is an interesting way of naming unit tests.

I would appreciate if you can append the ones which have helped you.

Rhino Mocks Links

I am no mockist. But I had to upgrade myself on this for one of my clients. Below are the few links I found useful. Hope they will help you as well. You can download Rhino Mocks here.
If I were to give you only one link, I would give you this one by Stephen Walther. Most accurate, to the point definition of mock types (strict, dynamic & partial) can be found here. If you prefer to get deeper or want an immediate answer to your question you can try out official forum.
Of course it all starts here at creator’s (Ayende Rahien’s) offical site. A good writeup by creator (but slightly old I guess)  can be found here. Quick Reference can be found here.
Couple of other articles can be found here – Part I & Part II though I haven’t read them completely.

Classic article by martin fowler MocksVsStubs is an essential read as well one on Dependency Injection which is critical in order to leverage on Rhino Mocks. The code sample below by me is an example of state based vertification using Stubs. To see a behavior based verification test in action using mocks you can refer this example.

I have slightly altered the code of Stephen Walter to take it a bit closer to real world (Though I only hope so :) ). Suppose you have 2 interfaces IProduct & IProductRepository

public interface IProduct
{
        string Name { get; set; }
        int Price { get; set; }
}

public interface IProductRepository
{
        List<IProduct> GetProducts(); // Get the products from database
}

You don’t have the concrete implementations of either & you have been asked to implement a class called ProductManager which decides on whether a product is eligible for discounts. It also sums up the total bill for a group of products passed to it. Using Dependency injection the code for ProductManager class would like below (you can ofcourse follow a TDD approach by writing Unit Test first but I am just trying to simplify things here).

public class ProductManager
{
        public int GetTotalPrice(IProductRepository productRepository) // Dependency being injected rather than instantiation
        {
            int total = 0;
            List<IProduct> products = productRepository.GetProducts();
            foreach (var product in products)
            {
                total += GetDiscountedPrice(product); // Get discounted price as below
            }
            return total;
        }

        public int GetDiscountedPrice(IProduct product) // Ditto
        {
            if (product.Price > 1000)
                return product.Price – 50; // If Price is more than 1000 give a discount of 50
            return product.Price;
        }
}

Now let’s say you want to test the above code. For that you require concrete implementations of interfaces & setup the corresponding infrastructure as required. But those implementations are currently being worked on you don’t have time to wait for them to be available. You want to move ahead quickly with unit test related to your code. Here comes Rhino Mocks to your rescue.

[TestClass] // VSTS attributes, you can use NUnit as well
public class ProductManagerTests
{
        [TestMethod]
        public void GetDiscountedPriceTest()
        {
            ProductManager manager = new ProductManager();

            IProduct product = MockRepository.GenerateStub<IProduct>(); // Create a stub
            product.Name = “TV”;
            product.Price = 12000;

            int discountedPrice = manager.GetDiscountedPrice(product); // Passing stub as a parameter
            Assert.AreEqual(11950, discountedPrice);
        }

        [TestMethod]
        public void GetTotalPriceTest()
        {
            ProductManager manager = new ProductManager();

            MockRepository mockRepository = new MockRepository(); // Create the repository as we need for the methods like record, playback etc.

            IProduct _p1 = mockRepository.Stub<IProduct>(); // Another way to create stub. N.B. you can replace GetDiscountedPriceTest with this syntax although formal is more crisp.
            IProduct _p2 = mockRepository.Stub<IProduct>();
            IProduct _p3 = mockRepository.Stub<IProduct>();

            _p1.Name = “A”;
            _p1.Price = 1050;
            _p2.Name = “B”;
            _p2.Price = 1050;
            _p3.Name = “C”;
            _p3.Price = 1050;

            List<IProduct> _fakeProducts =
                new List<IProduct>() {_p1, _p2, _p3}; // Your fake products, without mocks you would have to get them from a persistent store like DB.

            IProductRepository productRepository =
                mockRepository.Stub<IProductRepository>();

            using(mockRepository.Record()) // Record the call, and if the call is made later to the recorded method the result returned will the one you have setup
            {
                SetupResult
                    .For(productRepository.GetProducts())
                    .Return(_fakeProducts);
            }

            int totalPrice = manager.GetTotalPrice(productRepository);
            Assert.AreEqual(3000, totalPrice);
        }
}

For a  more thorough understanding refer to links at the starting of the article. Happy mocking :) .

Follow

Get every new post delivered to your Inbox.

Join 159 other followers