Server Side Caching using System.Runtime.Caching

Data elements such as location details or item prices are not subject to change on a transaction basis which means that they do not change frequently. If this kind of data is required for view and controller renderings in Sitecore, being able to get the data locally enhances web site performance manifold as there is no need to go to the external services or databases that house this data on every request.

One of the ways to achieve this performance gain is to identify and duplicate the needed data in Sitecore itself and reach out to Sitecore to get the same when needed – putting into effect Sitecore’s inherent caching capabilities when fetching this data. However, this leads to 2 sources of truth, necessitating updates to the data in the real source as well as Sitecore.

Another way is to use server side caching – where the capabilities offered by the .Net assembly System.Runtime.Caching are utilized to create in memory caches that can store and retrieve custom objects. This is best suited to controller renderings that need externally sourced data to process information before rendering. This method depends on the Content Management and Content Delivery servers having sufficient memory to support the in-memory caches and also strength in terms of CPU. Depending on the available infrastructure and the type and size of the data you wish to store in the in-memory cache this may or may not be an issue.

In this blog post we will look at using System.Runtime.Caching to achieve server side caching for custom objects.

Models involved in the caching sample

In the sample application that I have developed, we will be dealing with a simple class whose objects we will be storing in the cache. This is the ‘Person’ class as shown below:


public class Person
{
public string FirstName { get; set; }

public string LastName { get; set; }

public string PhoneNumber { get; set; }
}

I will also be using a generic ‘CacheResult’ class to hold the value obtained from the cache and any errors that we will need to report while retreiving data from the cache as below:


public class CacheResult<TCachedModel>
{
public TCachedModel CacheValue { get; set; }

public CacheErrorType CacheError { get; set; }
}

‘CacheErrorType’ is an enumeration as follows:


public enum CacheErrorType
{
NoError,

ItemNotFoundInCache,

CacheDoesNotExist,

CacheKeyCouldNotBeConstructed
}

Setting up the cache

Setting up the System.Runtime.Caching.MemoryCache is as simple as creating a Singleton instance of the MemoryCache class. The constructor of the ‘MemoryCache’ class takes a NameValueCollection which contains the names and values of certain configurations that govern the working of the in-memory cache. Chief among them are the following:

  • cacheMemoryLimitMegabytes – The limit of the amount of memory the cache can use on the server
  • physicalMemoryLimitPercentage – The percentage of server memory to use
  • pollingInterval – The maximum time that can occur before memory statistics are updated

The values that one assigns to the these configurations vary by need and is a cache design time consideration. In the sample application the values are 15 MB, 10 MB and “02:00:00” respectively.

Another typical configuration that is made available (albeit for later use) is the individual cache item level configuration of timeout for the item. This is set through the ‘AbsoluteExpiration’ property of the class ‘CacheItemPolicy’. Another Singleton property ‘PersonCacheItemPolicy’ in the sample application exposes this item level configuration. This property can be used when adding an item to the already created and configured cache.

How to do it in Sitecore?

One of the ways to instantiate the Singleton instance of System.Runtime.Caching.MemoryCache is to have it instantiated and configured in the ‘initialize’ pipeline of Sitecore. This way the instance is available to Sitecore and the logic in the controller renderings before any renderings need to add to or read from the cache.

The initialization and configuration of the cache is as depicted in the class below:


public class InitializePersonCache
{
// The limit of the amount of memory the cache can use on the server
private const string ConstCacheMemoryLimitMegabytes = "cacheMemoryLimitMegabytes";
// Percentage of server memory to use
private const string ConstPhysicalMemoryLimitPercentage = "physicalMemoryLimitPercentage";
// The maximum time that can occur before memory statistics are updated.
private const string ConstPollingInterval = "pollingInterval";

public static MemoryCache PersonCache;

public static CacheItemPolicy PersonCacheItemPolicy;

public void Initialize()
{
if (PersonCache == null)
{
PersonCache = new MemoryCache("PersonCache", GetCacheConfig());
PersonCacheItemPolicy = GetCacheItemPolicy();
}
else
{
MessageBox.Show("The cache is already set up and configured!");
}
}

private NameValueCollection GetCacheConfig()
{
NameValueCollection config = new NameValueCollection
{
{ ConstCacheMemoryLimitMegabytes, ConfigurationManager.AppSettings.Get("PersonCacheMemoryLimitMegabytes") },
{ ConstPhysicalMemoryLimitPercentage, ConfigurationManager.AppSettings.Get("PersonCachePhysicalMemoryLimitPercentage") },
{ ConstPollingInterval, ConfigurationManager.AppSettings.Get("PersonCachePollingInterval") }
};

return config;
}

private CacheItemPolicy GetCacheItemPolicy()
{
var cacheDefaultTimeout = Convert.ToInt32(ConfigurationManager.AppSettings.Get("PersonCacheTimeout"));
CacheItemPolicy cachePolicy = new CacheItemPolicy
{
AbsoluteExpiration = ConvertIntToMinDateTimeOffSet(cacheDefaultTimeout)
};

return cachePolicy;
}

private static DateTimeOffset ConvertIntToMinDateTimeOffSet(int cacheExpiryIntervalInMinute)
{
return new DateTimeOffset(DateTime.Now.AddMinutes(cacheExpiryIntervalInMinute));
}
}

In the sample application the instantiation and configuration has been called on the manual click of a button.

Code infrastructure to interact with the in-memory cache

Typically one needs to read from and add to the cache. Depending on the situation and requirements there might also be a need to update a certain element in the cache. I recommend putting in place an interface based approach to enable these interactions with the cache. This allows the application to not depend directly on the System.Runtime.Caching.MemoryCache but on objects that implement certain contracts and guarantee a result. The biggest advantage of this is that one can easily replace the cache being used – today it is System.Runtime.Caching.MemoryCache tomorrow it may well be AppFabric caching – as long as the application gets the desired result from the cache.

With the above concept in mind the sample application contains the following interfaces:


public interface ICacheKeyConstructor<TInRequest, TOutKey>
{
TOutKey ConstructCacheKey(TInRequest incomingRequest);
}

public interface IAddCacheItemAdapter<Tvalue>
{
bool Execute(Tvalue cacheItem);
}

public interface IAddCacheItemAdapter<TKey, Tvalue>
{
bool Execute(TKey requestItem, Tvalue cacheItem);
}

public interface IGetCacheItemAdapter<Tkey, Tvalue>
{
Tvalue Execute(Tkey cacheKey);
}

In the following sections we will look at using these interfaces to interact with the cache that has already been instantiated and configured.

Adding items to the cache

Adding items to the cache includes 2 main ideas:

  1. Generation of a unique that is able to identify a item accurately.
  2. Implementation of the interface IAddCacheItemAdapter<Tvalue>

Typically, the approach used to construct a key is to use an element or combination of elements within the item itself that can identify the item uniquely. In our sample I am using the combination of the First and Last Name of the Person object. This is sufficient for our controlled code but may well be insufficient for other, more complex cases. In a situation where we are storing prices for products in the cache an example key could be: Country Code + State Code + Item SKU – a bottle of soda in the US in California is different from the same bottle in Minnesota. This is a critical aspect of caching items and must be thought out carefully.

Another thing to keep in mind while determining an algorithm to generate a key is that all parts of the program should generate the key for a given type of item in exactly the same manner. This ensures that the entire application identifies the same item in the same way – increasing the chances of one part of the application successfully getting an item from cache which was stored in the cache by a different part of the application. Once again, going the interface driven route and having a single implementation for a particular item’s key generation helps tremendously. If different parts of the application generate keys for the same item in different ways the chances of hitting the cache are lower – ultimately watering down all the performance benefits that we set out to achieve.

In our sample we have implemented a cache key generator for the Person object as follows:


public class PersonCacheKeyConstructor : ICacheKeyConstructor&lt;Person, string&gt;
{
// The key for the Person Cache is simple - the concatenated First Name and Last Name
public string ConstructCacheKey(Person incomingRequest)
{
var personCacheKey = string.Empty;

if (incomingRequest != null &amp;&amp;
!string.IsNullOrEmpty(incomingRequest.FirstName) &amp;&amp;
!string.IsNullOrEmpty(incomingRequest.LastName))
{
personCacheKey = string.Concat(incomingRequest.FirstName.Trim(), incomingRequest.LastName.Trim());
}

return personCacheKey;
}
}

In the process of adding a Person to the cache, one then uses the PersonCacheKeyConstructor to contruct the cache key for the incoming Person. If the key is not empty, the Person can be added to the cache as follows:


public class AddPersonToCache : IAddCacheItemAdapter&lt;Person&gt;
{
public bool Execute(Person cacheItem)
{
ICacheKeyConstructor&lt;Person, string&gt; personCacheKeyConstructor = new PersonCacheKeyConstructor();
var cacheKey = personCacheKeyConstructor.ConstructCacheKey(cacheItem);

if (!string.IsNullOrEmpty(cacheKey))
{
var personCacheItem = new CacheItem(cacheKey, cacheItem);
if (InitializePersonCache.PersonCache != null)
{
try
{
InitializePersonCache.PersonCache.Add(personCacheItem, InitializePersonCache.PersonCacheItemPolicy);
return true;
}
catch
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
}

Note the use of the static property PersonCacheItemPolicy on the InitializePersonCache class that is used while adding the Person to the cache. This property governs the life of the Person item in the cache.

The code that orchestrates the addition of the Person item in the cache is as follows:


private void btnAddToCache_Click(object sender, EventArgs e)
{
if (InitializePersonCache.PersonCache != null)
{
// Construct the Person item
if (!string.IsNullOrEmpty(txtFirstName.Text) &amp;&amp;
!string.IsNullOrEmpty(txtLastName.Text) &amp;&amp;
!string.IsNullOrEmpty(txtPhoneNumber.Text))
{
var personToAdd = new Person
{
FirstName = txtFirstName.Text.Trim(),
LastName = txtLastName.Text.Trim(),
PhoneNumber = txtPhoneNumber.Text.Trim()
};

IAddCacheItemAdapter&lt;Person&gt; addPersonToCacheAdapter = new AddPersonToCache();
if (addPersonToCacheAdapter.Execute(personToAdd))
{
MessageBox.Show(&quot;Person added successfully to cache!&quot;);
}
}
else
{
MessageBox.Show(&quot;First Name, Last Name and Phone Number are all required!&quot;);
}
}
else
{
MessageBox.Show(&quot;Person cache has not been set up! Please set up and configure the cache first.&quot;);
}
}

Typically the code to add an item to the cache is called in when the application fails to find a requested item in the cache in the first place. If the item is not found in the cache, then it should be fetched from the real source of the data and then added to the cache before being returned to the caller. In this way, the next time the item is searched it will be successfully found in the cache.

Getting items from the cache

In order to get an item from the cache, one needs to implement the interface IGetCacheItemAdapter<string, CacheResult<Person>> as follows:


public class GetPersonFromCache : IGetCacheItemAdapter&lt;string, CacheResult&lt;Person&gt;&gt;
{
public CacheResult&lt;Person&gt; Execute(string cacheKey)
{
var personFromCache = new CacheResult&lt;Person&gt;();

if (InitializePersonCache.PersonCache != null)
{
try
{
// Use the key to get the Person from Cache
personFromCache.CacheValue = InitializePersonCache.PersonCache.Get(cacheKey) as Person;
if (personFromCache.CacheValue == null)
{
personFromCache.CacheError = CacheErrorType.ItemNotFoundInCache;
}
else
{
personFromCache.CacheError = CacheErrorType.NoError;
}
}
catch
{
personFromCache.CacheValue = null;
personFromCache.CacheError = CacheErrorType.ItemNotFoundInCache;
}
}
else
{
personFromCache.CacheValue = null;
personFromCache.CacheError = CacheErrorType.CacheDoesNotExist;
}

return personFromCache;
}
}

Note how the CacheResult generic class has been instantiated for the Person type and how the code passes back the CacheErrorType if any.

The code that orchestrates the getting of an item from cache and getting the requested item from the real source if it not found in the cache is as follows. Note that the code also adds the item from the real source to the cache before returning it to the caller – incrementally improving site performance as more and more items of the same type are requested for processing by different parts of the application.


private void btnGetFromCache_Click(object sender, EventArgs e)
{
// Construct the cache key from the First Name and Last Name
if (!string.IsNullOrEmpty(txtPersonFirstName.Text) &amp;&amp;
!string.IsNullOrEmpty(txtPersonLastName.Text))
{
StringBuilder sb = new StringBuilder();
var cacheKey = string.Concat(txtPersonFirstName.Text.Trim(), txtPersonLastName.Text.Trim());

IGetCacheItemAdapter&lt;string, CacheResult&lt;Person&gt;&gt; getPersonFromCacheAdapter = new GetPersonFromCache();
var cacheResult = getPersonFromCacheAdapter.Execute(cacheKey);
if (cacheResult != null &amp;&amp;
cacheResult.CacheValue != null &amp;&amp;
cacheResult.CacheError == CacheErrorType.NoError)
{
sb.Clear();
sb.AppendLine(&quot;Person found in cache!&quot;);
sb.AppendLine(string.Concat(&quot;First Name: &quot;, cacheResult.CacheValue.FirstName));
sb.AppendLine(string.Concat(&quot;Last Name: &quot;, cacheResult.CacheValue.LastName));
sb.AppendLine(string.Concat(&quot;Phone Number: &quot;, cacheResult.CacheValue.PhoneNumber));
MessageBox.Show(sb.ToString());
}
else
{
// Get the Person from the external source and add the same to the cache for the next time the Person is searched
var personFromExternalSource = SamplePersonCollection.PersonsFromExternalSource.Where(person =&gt; person.FirstName == txtPersonFirstName.Text.Trim() &amp;&amp; person.LastName == txtPersonLastName.Text.Trim()).First();

sb.Clear();
sb.AppendLine(&quot;Person not found in cache - getting from external source - will also add to the cache!&quot;);
sb.AppendLine(string.Concat(&quot;First Name: &quot;, personFromExternalSource.FirstName));
sb.AppendLine(string.Concat(&quot;Last Name: &quot;, personFromExternalSource.LastName));
sb.AppendLine(string.Concat(&quot;Phone Number: &quot;, personFromExternalSource.PhoneNumber));
MessageBox.Show(sb.ToString());

IAddCacheItemAdapter&lt;Person&gt; addPersonToCacheAdapter = new AddPersonToCache();
if (addPersonToCacheAdapter.Execute(personFromExternalSource))
{
MessageBox.Show(&quot;Person added successfully to cache!&quot;);
}
}
}
else
{
MessageBox.Show(&quot;Both First and Last Names are required to get a Person!&quot;);
}
}

Conclusion

Some of the important concepts we looked at were the use of the capabilities offered by the .Net assembly System.Runtime.Caching as another way of implementing server side in-memory caching for objects sourced externally, the use of an interface based approach for interacting with the cache, the importance of appropriately generating cache item keys to keep the intended performance gains and also ways to interact with the cache that help in incrementally increasing performance as more and more objects of the same type keep getting added to the application’s memory space.

Advertisements

Unit Testing – A Sample Approach

Any explanation of Unit Testing is incomplete without a definition of a ‘Unit’ up front.

A unit can be defined as the smallest piece of code that ideally discharges a single responsibility, is aware of what is needed by it to perform that responsibility, is aware of the output it generates and finally is aware of the other units of code that it is dependent on to successfully perform its responsibility. An added attribute of a Unit is its ability to be tested in isolation.

In this blog I will look at how one can develop unit tests for units of code that are aware of their responsibility, inputs, outputs and dependencies. In order to gain an overview of how one can write such methods please read my earlier blog – Dependency Injection – A Foundation.

We will also look at the role of mocking in providing the necessary isolation for the unit being tested. MoQ is a popular framework for supplying fully constructed objects that a unit is dependent on to the unit. It can be obtained for local use from here. References can be found at the bottom of the blog.

Unit Testing and its Aim

A good definition of unit testing is as outlined by Roy Osherove: A unit test is an automated piece of code that invokes a unit of work in the system and then checks a single assumption about the behavior of that unit of work.

The aim of unit testing is to gather a set of assumptions and make sure that in all cases the unit of work returns the expected result. If the unit of work does not return the expected result the unit test has failed. The important thing to note here is that the set of assumptions should include scenarios that test all branches of logic within the unit of work and also how the unit of work would react in case illegal or empty input parameters are provided to it.

Setting up Unit Testing

Let’s continue to look at the set of interfaces, classes and methods that we developed for Dependency Injection – A Foundation. The first step in setting up unit testing is to add a unit testing project to your solution – in Visual Studio it is available as a template and can be added as shown below.

Adding_a_Unit_Testing_Project_in_Visual_Studio

Additional references will need to be added to MoQ and to Castle.Core which is the DI framework internally used by MoQ. Another important reference that you will need to add is the assembly that holds all the units of work that you wish to unit test.

Simple unit tests for units that do not depend on other units

In my previous code samples an example of a unit of work that is aware of its inputs and output and does not depend on other units of work would be the method “CalculateOilChangeCost” in the class “OilChangeCostCalculator”. This class implements the interface “ICalculateOilChangeCost”. I am reproducing the class here so that you can readily review the logic:


public class OilChangeCostCalculator : ICalculateOilChangeCost
{
 public double CalculateOilChangeCost(DateTime lastServiceDate)
 {
 var oilChangeCost = 0;

// Validations
 if (lastServiceDate &gt; DateTime.Now) 
 {
 // -1 denotes an error: Last Service Date cannot be in the future
 return -1;
 }

// If the Last Service Date was less than 90 days ago then an Oil Change is $0
 // If the Last Service Date was more than or equal to 90 days ago but less than 180 days ago then an Oil Change is $25
 // If the Last Service Date was more than or equal to 180 days ago then an Oil Change is $50
 if ((DateTime.Now - lastServiceDate).TotalDays &gt;= 90 &amp;&amp;
 (DateTime.Now - lastServiceDate).TotalDays &lt; 180)
 {
 oilChangeCost = 25;
 }

if ((DateTime.Now - lastServiceDate).TotalDays &gt;= 180)
 {
 oilChangeCost = 50;
 }

return oilChangeCost;
 }
}

The method “CalculateOilChangeCost” performs a single responsibility of determining the cost of an oil change. It takes in the last servicing date and returns the cost of oil change. As can be seen the logic checks to see if the servicing date is in the future, and if it is, the method returns an error code (one could also throw a custom exception here). If the servicing date is appropriate then depending on how long ago the vehicle was serviced a cost for oil change is calculated.

What would be an initial set of assumptions to be able to test this unit of work? Given the layout of the logic, a good set of assumptions that would test all lines of code would be as follows:

  • Error is returned when last service date is in the future
  • Oil change cost is 0 when vehicle has been serviced between 0 and 89 days ago
  • Oil change cost is 25 when vehicle has been serviced between 90 and 179 days ago
  • Oil change cost is 50 when vehicle has been serviced more than 180 days ago

To be able to write unit tests for the assumptions above you will need to introduce a “Unit Test Class” to your unit test project – in this case I have added the class “OilChangeCostCalculatorTests”. This class is decorated by the attribute “[TestClass]” and each of the test within are decorated by the attribute “[TestMethod]”. A test method in this simple scenario would be instantiating the class and calling the unit of work within it by passing a servicing date and then asserting whether the returned value matches the assumption for which the test was written. The code below shows the tests written for all 4 of the assumptions above.


[TestClass]
public class OilChangeCostCalculatorTests
{
[TestMethod]
public void Error_Is_Returned_When_Last_Service_Date_Is_In_The_Future()
{
OilChangeCostCalculator oilChangeCostCalc = new OilChangeCostCalculator();
var oilChangeCost = oilChangeCostCalc.CalculateOilChangeCost(new DateTime(2016, 09, 08));
Assert.IsTrue(oilChangeCost == -1);
}

[TestMethod]
public void Oil_Change_Cost_Is_0_When_Vehicle_Has_Been_Serviced_Between_0_And_89_Days_Ago()
{
OilChangeCostCalculator oilChangeCostCalc = new OilChangeCostCalculator();
var oilChangeCost = oilChangeCostCalc.CalculateOilChangeCost(new DateTime(2016, 08, 01));
Assert.IsTrue(oilChangeCost == 0);
}

[TestMethod]
public void Oil_Change_Cost_Is_25_When_Vehicle_Has_Been_Serviced_Between_90_And_179_Days_Ago()
{
OilChangeCostCalculator oilChangeCostCalc = new OilChangeCostCalculator();
var oilChangeCost = oilChangeCostCalc.CalculateOilChangeCost(new DateTime(2016, 03, 01));
Assert.IsTrue(oilChangeCost == 25);
}

[TestMethod]
public void Oil_Change_Cost_Is_50_When_Vehicle_Has_Been_Serviced_More_Than_180_Days_Ago()
{
OilChangeCostCalculator oilChangeCostCalc = new OilChangeCostCalculator();
var oilChangeCost = oilChangeCostCalc.CalculateOilChangeCost(new DateTime(2016, 01, 01));
Assert.IsTrue(oilChangeCost == 50);
}
}

Visual Studio allows one to run and debug all the tests within a test class. By simply right-clicking anywhere withing the class editor one gets the option to “Run Tests” which then displays the output of the tests in question in the “Test Explorer” window as shown below. In this case all 4 tests matched the assumptions that they were written for and hence passed.

Running_Unit_Tests_in_Visual_Studio

Unit tests for units that depend on other units

Mocking

One of the concepts I discussed earlier in the blog was that of a unit having the ability of being tested in isolation. A simple example of an isolated unit would be the method “CalculateOilChangeCost” in the class “OilChangeCostCalculator” that we just saw in the last section. It is isolated by default because it does not depend on any other unit of work. However, this is seldom the case. More often then not one encounters units that are dependent on several other units for functioning. How can such units be isolated from their dependencies? The answer lies in the unit of work not being flustered about its dependencies and if they would function correctly in a given situation – the test is for the unit itself and not its dependencies.

A paradigm that allows a unit test writer to keep the unit isolated is supplying the unit with constructed units of work that the unit is dependent on. In a way, telling the unit “Dont worry about the dependencies and whether they are accurate for this assumption. Just take what I give you and assume it is right and tell me what would your output be for this input.”. This supply of constructed units of work while testing the unit in isolation is done when other units of work are not functioning as part of an up and running application – something that makes it necessary to mock (or fake) the dependencies. One of the fundamental concepts that makes this possible is Inversion or Control or having the unit that is being tested not depend on the concrete instances of the dependencies but having it be dependent on a contract that the dependencies must abide by. In this way any instance of the dependency could be supplied to the unit as long as it abides by the contract. It could be a fake instance too – constructed precisely to suit the assumption the unit is being tested for.

As indicated earlier, MoQ is a popular framework that allows one to create and supply mock instances of dependencies to units. It also allows one to do some other interesting things to ensure code coverage is as comprehensive as one chooses it to be. We will see some of this in the next section.

A unit that depends on other units

In previous code samples an example of a unit that is dependent on other units would be the method “CalculateServiceCost” in the class “ServiceCostCalculator”. The class “ServiceCostCalculator” implements the interface “ICalculateServiceCost”. I am reproducing it here for a quick review of the logic.


public class ServiceCostCalculator : ICalculateServiceCost
{
 #region Interfaces the class is dependent on
 private readonly ICheckIfOilChangeIsRequired _checkIfOilChangeIsRequired;
 private readonly ICalculateOilChangeCost _calculateOilChangeCost;
 #endregion

public ServiceCostCalculator(
 ICheckIfOilChangeIsRequired checkIfOilChangeIsRequired,
 ICalculateOilChangeCost calculateOilChangeCost) 
 {
 _checkIfOilChangeIsRequired = checkIfOilChangeIsRequired;
 _calculateOilChangeCost = calculateOilChangeCost;
 }

public double CalculateServiceCost(int year, DateTime lastServiceDate)
 {
 // Validations
 if (lastServiceDate &gt; DateTime.Now) 
 {
 // -1 denotes an error: Last Service Date cannot be in the future
 return -1;
 }

// The Standard Cost of Service is $35
 // If the Vehicle is more than 5 years old add another $35
 // Check if an Oil change is required - if yes add the amount returned by the Oil Change Cost calculator
 double vehicleServiceCharge = 35;

// Get the year from the current date
 var currentYear = DateTime.Now.Year;

if (currentYear - year &gt; 5) 
 {
 vehicleServiceCharge += 35;
 }

if (_checkIfOilChangeIsRequired.CheckIfOilChangeIsRequired(lastServiceDate)) 
 {
 var oilChangeCost = _calculateOilChangeCost.CalculateOilChangeCost(lastServiceDate);
 if (oilChangeCost != -1)
 {
 vehicleServiceCharge += oilChangeCost;
 }
 else 
 {
 return oilChangeCost;
 }
 }

return vehicleServiceCharge;
 }
}

As can be seen, the unit calculates the cost of servicing a vehicle but depends on other units to tell it if an oil change is required and what the cost of that oil change would be.

What would be an initial set of assumptions to be able to test this unit of work? Given the layout of the logic, a sampling of assumptions that would be as follows:

  • Error Is Returned When Last Service Date Is In The Future
  • AppropriateCost Is Returned When Vehicle Is More Than 5 Years Old Serviced Less Than 90 DaysAgo
  • AppropriateCost Is Returned When Vehicle Is More Than 5 Years Old Serviced More Than 90 Days Ago But Less Than 180 Days Ago
  • AppropriateCost Is Returned When Vehicle Is More Than 5 Years Old Serviced More Than 180 Days Ago

The first assumption can be unit tested by writing a test as follows


[TestMethod]
public void Error_Is_Returned_When_Last_Service_Date_Is_In_The_Future()
{
 // Arrange all dependencies that are required by the ServiceCostCalculator class's CalculateServiceCost method 
 Mock&lt;ICheckIfOilChangeIsRequired&gt; mockOilChangeChecker = new Mock&lt;ICheckIfOilChangeIsRequired&gt;();
 Mock&lt;ICalculateOilChangeCost&gt; mockOilChangeCostCalculator = new Mock&lt;ICalculateOilChangeCost&gt;();

ServiceCostCalculator serviceCostCalc = new ServiceCostCalculator(mockOilChangeChecker.Object, mockOilChangeCostCalculator.Object);

// Act - Call the ServiceCostCalculator class's CalculateServiceCost method 
 // Pass in the Last Date of Service as a future date and assert that the return value is -1
 var serviceCost = serviceCostCalc.CalculateServiceCost(2006, new DateTime(2016, 09, 10));

 // Assert whether the outcome 
 Assert.IsTrue(serviceCost == -1);
}

There are 2 salient points to note here:
1) MoQ allows one to create mock or fake objects that abide by a certain contract or interface. ‘mockOilChangeChecker’ and ‘mockOilChangeCostCalculator’ are the 2 mock objects that need to be constructed for the unit being tested to work. They abide by the interfaces ‘ICheckIfOilChangeIsRequired’ and ‘ICalculateOilChangeCost’ respectively.
2) The ‘Object’ property on the mock instance allows one access to the concrete object that needs to be passed on to the unit being tested.

The second assumption can be unit tested by writing a test as follows


[TestMethod]
public void AppropriateCost_Is_Returned_When_Vehicle_Is_More_Than_5_Years_Old_Serviced_Less_Than_90_Days_Ago()
{
// Arrange all dependencies that are required by the ServiceCostCalculator class's CalculateServiceCost method
Mock<ICheckIfOilChangeIsRequired> mockOilChangeChecker = new Mock<ICheckIfOilChangeIsRequired>();
Mock<ICalculateOilChangeCost> mockOilChangeCostCalculator = new Mock<ICalculateOilChangeCost>();

ServiceCostCalculator serviceCostCalc = new ServiceCostCalculator(mockOilChangeChecker.Object, mockOilChangeCostCalculator.Object);

// Act - Call the ServiceCostCalculator class's CalculateServiceCost method
// Pass in the Vehicle Year as 2006 and Last Service Date as 2016-06-08 and assert that the Service Cost is $70
var serviceCost = serviceCostCalc.CalculateServiceCost(2006, new DateTime(2016, 06, 08));

// Verify that the CheckIfOilChangeIsRequired method was called once on the Mock object of ICheckIfOilChangeIsRequired with the specified DateTime passed in
mockOilChangeChecker.Verify(oilChangeChecker => oilChangeChecker.CheckIfOilChangeIsRequired(It.Is<DateTime>(dt => (dt.Year == 2016 && dt.Month == 06 && dt.Day == 08))), Times.Once);

// Verify that the CalculateOilChangeCost method was not called on the Mock object of the ICalculateOilChangeCost with the specified DateTime passed in
// This is because in the test the vehicle was serviced less than 90 days ago
mockOilChangeCostCalculator.Verify(oilChangeCostCalculator => oilChangeCostCalculator.CalculateOilChangeCost(It.Is<DateTime>(dt => (dt.Year == 2016 && dt.Month == 06 && dt.Day == 08))), Times.Never);

// Assert whether the outcome
Assert.IsTrue(serviceCost == 70);
}

The salient points to note here are:
1) We can verify whether the unit being tested actually called on a certain method on its dependency. For example, the test verifies whether the method ‘CheckIfOilChangeIsRequired’ was called on mockOilChangeChecker.Object.
2) We can verify that the parameters passed on to the inner method are what we expected to be passed.
3) We can write the test to verify the number of times the inner method was called
4) All these verifications must pass in order for the test to pass.

The lines of code specific to these are


mockOilChangeChecker.Verify(oilChangeChecker => oilChangeChecker.CheckIfOilChangeIsRequired(It.Is<DateTime>(dt => (dt.Year == 2016 && dt.Month == 06 && dt.Day == 08))), Times.Once);
mockOilChangeCostCalculator.Verify(oilChangeCostCalculator => oilChangeCostCalculator.CalculateOilChangeCost(It.Is<DateTime>(dt => (dt.Year == 2016 && dt.Month == 06 && dt.Day == 08))), Times.Never);

The third assumption can be unit tested by writing a test as follows


[TestMethod]
public void AppropriateCost_Is_Returned_When_Vehicle_Is_More_Than_5_Years_Old_Serviced_More_Than_90_Days_Ago_But_Less_Than_180_Days_Ago()
{
// Arrange all dependencies that are required by the ServiceCostCalculator class's CalculateServiceCost method
Mock<ICheckIfOilChangeIsRequired> mockOilChangeChecker = new Mock<ICheckIfOilChangeIsRequired>();
Mock<ICalculateOilChangeCost> mockOilChangeCostCalculator = new Mock<ICalculateOilChangeCost>();

ServiceCostCalculator serviceCostCalc = new ServiceCostCalculator(mockOilChangeChecker.Object, mockOilChangeCostCalculator.Object);

// Set up the Mocks to return appropriate values in accordance with the tests
// The Mocks need to be set up to return the appropriate values in accordance with the tests as the logic being unit tested is not for the mocked dependencies
mockOilChangeChecker.Setup(oilChangeChecker => oilChangeChecker.CheckIfOilChangeIsRequired(It.IsAny<DateTime>())).Returns(true);
mockOilChangeCostCalculator.Setup(oilChangeCostCalculator => oilChangeCostCalculator.CalculateOilChangeCost(It.IsAny<DateTime>())).Returns(25);

// Act - Call the ServiceCostCalculator class's CalculateServiceCost method
// Pass in the Vehicle Year as 2006 and Last Service Date as 2016-03-08 and assert that the Service Cost is $95
var serviceCost = serviceCostCalc.CalculateServiceCost(2006, new DateTime(2016, 03, 08));

// Verify that the CheckIfOilChangeIsRequired method was called once on the Mock object of ICheckIfOilChangeIsRequired with the specified DateTime passed in
mockOilChangeChecker.Verify(oilChangeChecker => oilChangeChecker.CheckIfOilChangeIsRequired(It.Is<DateTime>(dt => (dt.Year == 2016 && dt.Month == 03 && dt.Day == 08))), Times.Once);

// Verify that the CalculateOilChangeCost method was called once on the Mock object of the ICalculateOilChangeCost with the specified DateTime passed in
mockOilChangeCostCalculator.Verify(oilChangeCostCalculator => oilChangeCostCalculator.CalculateOilChangeCost(It.Is<DateTime>(dt => (dt.Year == 2016 && dt.Month == 03 && dt.Day == 08))), Times.Once);

// Assert whether the outcome
Assert.IsTrue(serviceCost == 95);
}

The salient point to note here is
1) We have used the MoQ ability to ensure that the mock objects that are being passed to the unit being tested return set values that are in accordance with our assumption for the test.

The lines of code specific to these are


mockOilChangeChecker.Setup(oilChangeChecker => oilChangeChecker.CheckIfOilChangeIsRequired(It.IsAny<DateTime>())).Returns(true);
mockOilChangeCostCalculator.Setup(oilChangeCostCalculator => oilChangeCostCalculator.CalculateOilChangeCost(It.IsAny<DateTime>())).Returns(25);

Conclusion

As we have seen, a combination of principles such as Single Responsibility and Inversion of Control and patterns such as Dependency Injection and frameworks such as MoQ and Castle allow us to write code that is well suited to unit testing from the get go. Having unit tests in place for all known logic paths promotes code re-usability in that it allows common functions or responsibilities to be written separately and reused across areas of the application. When a change is made to the common function it can be unit tested by simply running the tests. If all tests pass, it ensures that the changes have not broken the logic flow in the unit and the other parts of the application will not suffer due to the change. The amount of manual regression testing for the impacted components is phenomenally reduced.

References

  • Quick start on MoQ: https://github.com/Moq/moq4/wiki/Quickstart
  • Handy tips on writing  unit tests using MoQ: http://www.developerhandbook.com/unit-testing/writing-unit-tests-with-nunit-and-moq/
  • The Art of Unit Testing in Ruby, Java & .NET – by Roy Osherove – http://artofunittesting.com/definition-of-a-unit-test/

Dependency Injection – A Foundation

Dependency Injection Pattern (DI) in itself allows a class’s dependencies to be ‘given’ to the class instead of the class having to create new instances of the dependencies within itself. However, it is prudent to step back and understand some fundamentals that allow one to implement DI and reap the benefits that DI has to offer in terms of more maintainable and accurate code. The next section describes in brief some of these principles – a look at the references listed at the end of the blog is recommended for a deeper understanding.

Design Fundamentals

High Cohesion
Cohesion is a measurement of how responsibilities a class performs are related to each other. The relationships between the responsibilities of a class can be strong – which means they are all geared towards achieving the same goal or are all performing operations that fall within the same functional area. They can also be weak – which means that a class has responsibilities which are not necessarily in the same functional area.

A good real world example would be a car. All responsibilities related to steering being in one class is an example of strong relationships and high cohesion. So is all responsibilities of acceleration being in one class. On the other hand if one were to design a class which would handle some responsibilities of steering and some of acceleration as well, then those responsibilities would not be cohesive – think of the car turning and accelerating at the same time due to some complicated flaw in the logic due to mixed up responsibilities – it would be better to create 2 different classes with more cohesive responsibilities and have them interact with each other for the smooth functioning of the car.

In general high cohesion between the responsibilities of a class is desired.

Low Coupling
Coupling is a measurement of how much 2 different classes are dependent on each other. In the car example above, even if acceleration and steering would be separate, but if acceleration needs input from steering every time it performs an action then acceleration is coupled to steering. Coupling in itself is not bad and is necessary at times. But if one needs to change the code or implementation of acceleration every time the implementation of steering has changed then this would be an example of high coupling between acceleration and steering.

In general low coupling between 2 classes is desired.

Separation of Concerns

One way to achieve high cohesion and low coupling is the Separation of Concerns principle, i.e., identifying the unique and related responsibilities from the entire set of responsibilities that are at hand, grouping them into classes of their own and then deciding how these classes would interact with the outside world.

Interface Driven Development

The last point mentioned in ‘Separations of Concerns’ is related to determining how a related group of functions would interact with the outside world. This is achieved by writing a contract which clearly outlines the responsibilities and their input and output parameters. This contract is what the outside world knows about the class and what all modules wishing to interact with the related group of functions must abide by. The actual implementation of the methods themselves is abstracted away from the outside world and therefore can change at any time without impacting anyone else – as long as the contract is not changed. This contract is called the Interface.

One of the beautiful things that this offers is the ability to switch real implementations of an interface depending on the situation or just simply the ability to use mock implementations instead of real ones for unit testing. We will discuss this in detail in another blog.

Single Responsibility
In the ideal world this would mean that one class performs one and only one responsibility. In the real world this is seldom the case. Yet the attempt should always be to break down larger classes containing multiple responsibilities into smaller ‘units’ which are cohesive. This allows for a palette of classes that can be combined together to achieve larger results, yet which can be tested individually without having to test the entire functionality. Consider the example of acceleration and steering, that we talked about earlier, if the functions were mixed and there was problem with only acceleration, the mechanic would charge you for fixing acceleration and steering both instead of just acceleration!

Inversion of Control
When a function orchestrates several objects to achieve a certain result it is dependent on those objects. Any change in the implementation of those objects may result in the breakdown of the orchestrating function – even though by mistake. In other situations a change in the implementation of the objects might cause a change in the orchestrating function. In other words the orchestrating function is controlled to an extent by the lower level objects that it needs. If the orchestrating function would instead, depend on contracts that the lower level objects implemented, then the orchestrating function would be able to switch to any lower object that abides by that contract thus retaining control.

This is Inversion of Control – allowing both the higher and lower level classes to be decoupled from each other as long as they abide by the contract or interface agreement between them.

Sample Implementation of DI

Synopsis

We will be walking through a simple implementation to illustrate DI and also the principles mentioned above. This revolves around a small application built to determine the cost of servicing a vehicle. The cost is set, first, by the age of the vehicle and also depends on whether oil change is required. If an oil change is required the cost also depends on what the cost of the oil change is.

Basic Responsibilities

The primary responsibility of the application is to calculate the service cost – in a sense this is the high level class that is dependent on other lower level classes. The other responsibilities are around determining if an oil change is required and then determining the cost of the oil change.

Interfaces and Implementations

The responsibilities mentioned above are grouped into the following contracts or interfaces:


public interface ICheckIfOilChangeIsRequired
{
bool CheckIfOilChangeIsRequired(DateTime lastServiceDate);
}

public interface ICalculateOilChangeCost
{
double CalculateOilChangeCost(DateTime lastServiceDate);
}

public interface ICalculateServiceCost
{
double CalculateServiceCost(int year, DateTime lastServiceDate);
}

Sample implementations that abide by these contracts are as follows:


public class OilChangeDeterminator : ICheckIfOilChangeIsRequired
{
public bool CheckIfOilChangeIsRequired(DateTime lastServiceDate)
{
var oilChangeRequired = false;

// Validations
if (lastServiceDate > DateTime.Now)
{
return oilChangeRequired;
}

// If the Last Service Date was more than 90 days ago then an Oil Change is required
if ((DateTime.Now - lastServiceDate).TotalDays >= 90)
{
oilChangeRequired = true;
}

return oilChangeRequired;
}
}

Note: This class has only one responsibility (that of determining if an oil change is required) and depends on no other class.


public class OilChangeCostCalculator : ICalculateOilChangeCost
{
public double CalculateOilChangeCost(DateTime lastServiceDate)
{
var oilChangeCost = 0;

// Validations
if (lastServiceDate > DateTime.Now)
{
// -1 denotes an error: Last Service Date cannot be in the future
return -1;
}

// If the Last Service Date was less than 90 days ago then an Oil Change is $0
// If the Last Service Date was more than or equal to 90 days ago but less than 180 days ago then an Oil Change is $25
// If the Last Service Date was more than or equal to 180 days ago then an Oil Change is $50
if ((DateTime.Now - lastServiceDate).TotalDays >= 90 &&
(DateTime.Now - lastServiceDate).TotalDays < 180)
{
oilChangeCost = 25;
}

if ((DateTime.Now - lastServiceDate).TotalDays >= 180)
{
oilChangeCost = 50;
}

return oilChangeCost;
}
}

Note: This class has only one responsibility (that of determining the cost of an oil change) and depends on no other class.


public class ServiceCostCalculator : ICalculateServiceCost
{
#region Interfaces the class is dependent on
private readonly ICheckIfOilChangeIsRequired _checkIfOilChangeIsRequired;
private readonly ICalculateOilChangeCost _calculateOilChangeCost;
#endregion

public ServiceCostCalculator(
ICheckIfOilChangeIsRequired checkIfOilChangeIsRequired,
ICalculateOilChangeCost calculateOilChangeCost)
{
_checkIfOilChangeIsRequired = checkIfOilChangeIsRequired;
_calculateOilChangeCost = calculateOilChangeCost;
}

public double CalculateServiceCost(int year, DateTime lastServiceDate)
{
// Validations
if (lastServiceDate > DateTime.Now)
{
// -1 denotes an error: Last Service Date cannot be in the future
return -1;
}

// The Standard Cost of Service is $35
// If the Vehicle is more than 5 years old add another $35
// Check if an Oil change is required - if yes add the amount returned by the Oil Change Cost calculator
double vehicleServiceCharge = 35;

// Get the year from the current date
var currentYear = DateTime.Now.Year;

if (currentYear - year > 5)
{
vehicleServiceCharge += 35;
}

if (_checkIfOilChangeIsRequired.CheckIfOilChangeIsRequired(lastServiceDate))
{
var oilChangeCost = _calculateOilChangeCost.CalculateOilChangeCost(lastServiceDate);
if (oilChangeCost != -1)
{
vehicleServiceCharge += oilChangeCost;
}
else
{
return oilChangeCost;
}
}

return vehicleServiceCharge;
}
}

Note: This class has only one responsibility (that of determining the cost of service) and depends on 2 other abstractions or interfaces – one to determine if an oil change is required and the other to determine the cost of the oil change if an oil change is indeed required.

DI Setup

Setting up DI is about creating a catalog or container of interfaces that an application is exposed to and the concrete implementations that abide by those interfaces. For e.g., in our sample application the class ‘OilChangeDeterminator’ is a concrete implementation of the interface ‘ICheckIfOilChangeIsRequired’. When such a catalog is available to the application the higher level functions in the application can align to interfaces and have a DI framework supply the concrete implementations of those interfaces on demand.

One of the ways of declaring the higher level class’s dependencies is through the higher level class’s constructor – as we see in the class ‘ServiceCostCalculator’ and its constructor. The accompanying DI framework simply refers to the catalog of interfaces and their concrete implementations and passes the registered concrete implementation to the higher level class’s instance when the higher level class is ‘newed’ up, i.e., when the higher level class’s constructor is called.

There are many frameworks that help implement DI – some of the popular ones being Microsoft’s Unity Framework and Castle. We will be using Castle in our example.

The first step in setting up DI using Castle is implementing the interface ‘IWindsorContainer’ like below:


public class DependencyResolutions : IWindsorInstaller
{
public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
{
container.Register(Component.For<ICalculateServiceCost>().ImplementedBy<ServiceCostCalculator>());
container.Register(Component.For<ICheckIfOilChangeIsRequired>().ImplementedBy<OilChangeDeterminator>());
container.Register(Component.For<ICalculateOilChangeCost>().ImplementedBy<OilChangeCostCalculator>());
}
}

Then in the application’s start up code one needs to instantiate a container of type ‘IWindsorInstaller’ which is ‘WindsorContainer’. On that container object one can call the Install method like below:


public static IWindsorContainer Container = new WindsorContainer();
Container.Install(FromAssembly.This());

‘FromAssembly.This()’ locates the first implementation of ‘IWindsorInstaller’ in the current assembly and loads the ‘Container’ object with the concrete implementations of the interfaces that the application is exposed to.

DI in action

Once the ‘Container’ object is set up – Castle will automatically supply concrete implementations when requested by objects in their constructors or one can get the concrete implementation of an interface by resolving to it manually as shown below:


public partial class frmServiceDeterminator : Form
{
public static IWindsorContainer Container = new WindsorContainer();

#region Interfaces the class is dependent on
private ICalculateServiceCost _calculateServiceCost;
#endregion

public frmServiceDeterminator()
{
InitializeComponent();

// Initialize Dependency Injection
Container.Install(FromAssembly.This());
}

private void btnCalcServiceCost_Click(object sender, EventArgs e)
{
var vehicleYear = Convert.ToInt32(lstbYear.SelectedItem); // Un-boxing 😦
var lastServiceDate = dtPickServiceDate.Value;

_calculateServiceCost = Container.Resolve<ICalculateServiceCost>();

var serviceCost = _calculateServiceCost.CalculateServiceCost(vehicleYear, lastServiceDate);
if (serviceCost != -1)
{
lblServiceCost.Text = string.Concat("The cost of servicing is: $", serviceCost.ToString());
}
else
{
lblServiceCost.Text = "The cost of servicing cannot be calculated. Last Service Date is in the future!";
}
}

private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
}

Here, the form ‘frmServiceDeterminator’ is the start up form of the application and is dependent on the interface ‘ICalculateServiceCost’. This is then resolved to get the concrete implementation of ‘ICalculateServiceCost’ into the object ‘_calculateServiceCost’. The concrete implementation is an instance of the class ‘ServiceCostCalculator’ as determined by the DI container ‘DependencyResolutions’ as shown in the section ‘DI Setup’.

When creating an instance of the class ‘ServiceCostCalculator’, the DI framework realizes that ‘ServiceCostCalculator’ in turn depends on the interfaces ‘ICheckIfOilChangeIsRequired’ and ‘ICalculateOilChangeCost’ and resolves these dependencies to provide the instance of ‘ServiceCostCalculator’ with the concrete implementations of ‘ICheckIfOilChangeIsRequired’ and ‘ICalculateOilChangeCost’ which are ‘OilChangeDeterminator’ and ‘OilChangeCostCalculator’ respectively.

‘OilChangeDeterminator’ and ‘OilChangeCostCalculator’ are not dependent on any other interfaces and hence the cycle of DI stops there.

References and further reading

  • CLR via C# – Fourth Edition by Jeffrey Richter
  • Microsoft .Net: Architecting Applications for the Enterprise – Second Edition by Dino Esposito and Andrea Saltarello