In .NET there are two types of constructors, instance constructors and static constructors. Instance constructors are called when objects are instantiated, while static constructors get called before any member of the class is invoked for the first time.
Dependency Injection is a pattern where instantiation of objects that that are required by a class is handled outside of the class. The instances are then passed into the class through one of several mechanisms, most commonly through constructor parameters (referred to as Constructor Injection). This separation of concerns greatly enhances maintainability as well as provides a mechanism to isolate the code in your class from those dependencies, which facilitates unit testing. However, there are cases when you are faced with legacy code that doesn't use dependency injection and are held together by composition rather than aggregation.
In this case, you have the following options:
- Don’t test the code (not recommended)
- Refactor the code to support dependency injection (best long term solution, but not always practical for a variety of reasons)
- Use constructor mocking.
In order to illustrate the scenario, I have used an Entity Framework data container class that is created from default Northwind database.
After completing the wizard and opening the data container class (which I named NorthwindEntities), we see the following code:
To include this class in my tests, we have two options:
- Add NorthwindEntities section to the app.config of my test projects (as described above in app.config) and have it connect to the database each time
- Refactor the generated code to include a constructor that accepts a connection instance through Dependency Injection (and risk losing those changes when the classes get regenerated).
There is a third option when using
JustMock – create a mock of the concrete NorthWindEntities class that ignores the constructor. As the following code shows, this is extremely simple to do.
Specifying Constructor.Mocked when creating the mock will exclude any code inside the constructor from execution and remove the dependency on the database.
Remember that static constructors are invoked by the .NET runtime before any of the members are invoked. For many of the same reasons that instance constructors might need to be mocked to prevent side effects in tests, static constructors sometimes need to be mocked as well.
JustMock once again makes this very easy, although the syntax for mocking a static class is slightly different due to limitations in the .NET framework and working with static classed. For statics, we use the StaticConstructor.Mocked flag in the SetupStatic method, as shown in the following code sample:
Generally, if your code accesses external resources directly (such as databases or web services) then it is best to refactor it and implement Dependency Injection (please see
Phil Japikse’s
blog post on SOLID for more information). However, if you do not have access to the code or refactoring isn't an option (perhaps due to time, resource, or budget constraints) then being able to mocking the constructor (both for instances as well as static classes) while mocking the dependencies can save the day and make your tests fast, reliable, and maintainable.
Happy Coding!