Question

I was looking for some sample code for unit testing the strategy pattern method invocation.

I have a strategy pattern class LeaveCalculator and based on the leave type the factory class will instantiate the specific calculator.
For the Unit Test part I am trying to verify the proper Leave type calculation is invoked when we call the LeaveCalculator calculate method.

I am using C# for mocking RhinoMocks.

Please let me know any code samples to do this?

public static class LeaveCategoryFactory
{
private static List<ILeaveCalculation> categories = new List<ILeaveCalculation>();

public static ILeaveCalculation GetCategory(LeaveCalculationType calculationType)
{
  if (categories.Count == 0)
  {
    categories = Assembly.GetExecutingAssembly()
                       .GetTypes()
                       .Where(type => typeof(ILeaveCalculation).IsAssignableFrom(type) && type.IsClass)
                       .Select(type => Activator.CreateInstance(type))
                       .Cast<ILeaveCalculation>()
                       .ToList();
  }

  return categories.Where(x => x.CalculationType == calculationType).FirstOrDefault() as ILeaveCalculation;
}
}


[TestMethod]
public void ShouldReturnOneWhenAvailableLeaveCountIs12AndWorkedForAMonth()
{
  leaveCount.StartDate = systemDateTime.Now.Date.AddMonths(-1);
  leaveCount.EndDate = systemDateTime.Now.Date.AddMonths(11);
  leaveCount.Count = 12;
  var proRataClass = MockRepository.GenerateMock<ProRata>();
  var availableLeaveCount = proRataClass.Calculate(employee, systemDateTime.Now.Date, leaveCount);
  Assert.AreEqual(1, availableLeaveCount);
}
Was it helpful?

Solution

You have to redesign your code to use Dependency Injection. In your case define ILeaveFactoryCategory with GetCategory method. Make your ProRate class dependent on it (for example set factory by constructor parameter). Then mock the factory interface not calculator itself and set expectations for them. Use mocked object as parameter for class under test (LeaveCalculator). Verify expectations for you mocked object.

ILeaveCalculation expectedCalculator = new MyCalculator();
LeaveCalculationType expectedCalculationType = LeaveCalculationType.MyType;

ILeaveFactoryCategory factoryMock = MockRepository.GenerateMock<ILeaveFactoryCategory >();

factoryMock.Expect(f => f.GetCategory(Arg<LeaveCalculationType>.Is.Equal(expectedCalculationType)).Returns(expectedCalculator);

var proRataClass = new ProRata(factoryMock);
var availableLeaveCount = proRataClass.Calculate(employee, systemDateTime.Now.Date, leaveCount);

factoryMock.VerifyAllExpectations();

This code verifies that factory was used not the result of calculation. If you want to test results it's better to use Stub method instead of Expect and verify calculation result instead of expected behavior.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top