0

Unit Testing DateTime.Now

Posted in .Net, C#, Unit Testing at September 7th, 2009 by Drew / No Comments »

I’m sure alot of you have come across a method that uses DateTime.Now at some point in your lives. Normally this is fine and nobody blinks an eyelid… until we need to unit test it.

Consider the follow code:

public class MyEntity
 {
   public DateTime Created { get; set; }
 }

 public class MyRepository
 {
   public void UpdateMyEntity(MyEntity entity)
   {
     entity.Created = DateTime.Now;
   }
 }

Unless you are one of one of those fancy pants with TypeMock and the ability to fake DateTime.Now, the rest of use must look elsewhere for a solution. Here are three different ways to solve this.

1. Wrap your DateTime calls with another class

Some people prefer using a static “Clock” class to handle this which can be easily faked out during your unit testing.

public static class Clock
{
    public static Func<DateTime> Now = () => DateTime.Now;
}

This approach, while decoupling your dependency on System.DateTime is a bit of overkill and requires all developers on the project to be aware of it and to use it.

2.Use an Interface and your favourite Isolation Framework

public interface IClock
{
  DateTime Now {get;}
}

public class SystemClock : IClock
{
  public DateTime Now { get { return DateTime.Now; } }
}

You can now use an isolation framework such as Rhino.Mocks to fake the call to Now();

3. Use a DateTime Comparer that accepts a range

While not 100% accurate to the millisecond, this approach is my prefered approach as you don’t have to change to your code just to unit test it. No littering your code with IClock dependencies or using a delegate to return the current DateTime.Now (although one could argue that DateTime.Now shouldn’t be a property to begin with). This approach asserts that the Created property that is set in MyRepository.Update is within a certain range.

 /// <summary>
 /// Helper class to compare 2 values are within a certain range.
 /// </summary>
 public class DateComparer : IComparer<DateTime>
 {
 public TimeSpan MarginOfError { get; private set; }

 public DateComparer(TimeSpan marginOfError)
 {
   MarginOfError = marginOfError;
 }

  public int Compare(DateTime x, DateTime y)  // x = expected, y = actual
   {
     var margin = x - y;
     if (margin <= MarginOfError)
       return 0;
     return new Comparer(CultureInfo.CurrentUICulture).Compare(x, y);
   }
 }

You can now write the follow test:

public void MyRepository_UpdateTest()
 {
   var repository = new MyRepository();
   var entity = new MyEntity();
   repository.UpdateMyEntity(entity);
   var comparer = new DateComparer(new TimeSpan(0, 0, 0, 5));
   Assert.IsTrue(comparer.Compare(entity.Created, DateTime.Now) == 0);
 }
4

Unit Testing Expression Tree Equality

Posted in .Net, C#, Unit Testing at August 25th, 2009 by Ben / 4 Comments »

Sometimes you need to test whether two expressions are the same. However when you do a simple AreEqual() test on two expressions that look the same you get a negative result.

This method will fail

[TestMethod]
public void TestDoesNotWork()
{
  Expression<Func<int, int>> expressionA = x => x + 1;
  Expression<Func<int, int>> expressionB = x => x + 1;

  Assert.AreEqual(expressionA, expressionB);
}

This looks like it should work however it doesn’t. This is because when using anonymous expressions/delegates the CLR does some magic behind the scene to add a method on the fly, creating a new instance for every anonymous expression/delegate.

So if you have two expressions that are syntactically the same but not the same reference the easiest way to ensure they are the same is to compile the expression and invoke it comparing the resultant value.

[TestMethod]
public void TestDoesWork()
{
  Expression<Func<int, int>> expressionA = x => x + 1;
  Expression<Func<int, int>> expressionB = x => x + 1;

  Assert.AreEqual(expressionA.Compile().Invoke(3), expressionB.Compile().Invoke(3));
}

An alternate approach would be to de-construct each constituent part of the expression trees comparing each part as you go. This however is far more complex.

For a more real world example that involves using Rhino mocks and Expect calls please read on:

Read the rest of this entry »

Short Cut Keys to Run Tests:

• Ctl R, T: Run Tests in Current context (namespace, class, and method – ie. Based on where your cursor is within a file it determines the tests to run)
• Ctl R, C: Run Tests in Current Test Class
• Ctl R, N: Run Tests in Current Namespace
• Ctl R, S: Run All Tests in Solution
• Ctl R, D: Run the Tests in the Last Test Run
• Ctl R, F: Run the Failed Tests of the Last Test Run

0

I’m back

Posted in .Net, Asp.Net, C#, Unit Testing at October 30th, 2008 by Ben / No Comments »

After having 9 months off from doing .net (travelling, bumming and then a 3 month contract role as an architect in a coldfusion shop) I finally got myself a role doing what I love doing best – playing with .net and c#.

In the last 4 weeks I’ve been researching and prototyping apps that use

It’s been awesome to have the time and resources to touch across all of these technologies to enjoy their benefits and to loath the limitations.

All in all I reckon all of the technologies are a great addition to the .net stack and look forward to seeing them mature with each new release.

I look forward to documenting my findings as I find time to re-work them into don’t-give-away-IP examples.

0

Running VS Unit Tests stops IIS

Posted in .Net, Development, Unit Testing at October 24th, 2008 by Ben / No Comments »

We recently ran into this problem where we discovered that running our VS unit tests was killing IIS.

As with all problems, I like to break things down to the simplest scenario I can find and as such created a brand new unit test that did nothing to see if that still caused the problem – it did.

So knowing that it had nothing to do with any code that was web dependent I knew to start looking elsewhere.

Turns out the problem is caused by enabling code coverage on projects that are dependent on IIS – e.g. a web project.

Visual Studio Code Coverage

The simple solution is to disable code coverage on the problem-causing project OR alternately remove the dependency on IIS by modifying it to use the in-built Cassini web server.

0

Unit testing data access code

Posted in .Net, C#, Development, Unit Testing at February 19th, 2008 by Ben / No Comments »

A classic problem to unit testing code that modifies the underlying data in the database tables is that you need to find a way to revert back to the original database state so that the tests can be run over and over again.

Using the transaction capabilities provided with the .Net 2.0 framework and a unit testing framework you can achieve this easily.

The process:

  • Create a new transaction before each test.
  • Dispose (Rollback) the transaction after each test.


    using System.Data;

    [TestClass]
    public class DataProviderTest {

        private readonly DataProvider _dp = new DataProvider();
        private TransactionScope _transactionScope;

        [TestInitialize]
        public void TestInitialize() {
            _transactionScope = new TransactionScope();
        }

        [TestCleanup]
        public void TestCleanup() {
            _transactionScope.Dispose();
        }

        [TestMethod]
        public void InsertTest()
        {
            // modify the database
            ...
        }
    }

The following article tries to outline an approach for unit/integration testing using the Visual Studio Team System testing framework.

The article is long, but hopefully worth the read.

Defining terminology

Unit Testing vs. Integration Testing vs. System Testing

The following is taken from our good friends at Wikipedia.

Unit testing is a procedure used to validate that individual units of source code are working properly. A unit is the smallest testable part of an application, in OO the smallest unit is a method; which may belong to a base/super class, abstract class or derived/child class.

Ideally, each test case is independent from the others; mock objects and test harnesses can be used to assist testing a module in isolation. Unit testing is typically done by developers and not by end-users.

Integration testing is the phase of software testing in which individual software modules are combined and tested as a group. It follows unit testing and precedes system testing.

Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.

System testing of software is testing conducted on a complete, integrated system to evaluate the system’s compliance with its specified requirements. System testing falls within the scope of black box testing, and as such, should require no knowledge of the inner design of the code or logic. [1]

As a rule, system testing takes, as its input, all of the “integrated” software components that have successfully passed integration testing and also the software system itself integrated with any applicable hardware system(s). The purpose of integration testing is to detect any inconsistencies between the software units that are integrated together (called assemblages) or between any of the assemblages and the hardware. System testing is a more limiting type of testing; it seeks to detect defects both within the “inter-assemblages” and also within the system as a whole.

Whitebox Testing (goes hand in hand with Unit Testing)

Unit Tests typically are usually written with intimate knowledge of the unit being tested – which allows all paths within the unit to be covered by the tests ensuring complete code coverage.

Mocking frameworks such as Rhino provided utilities to help assert code paths are tested.

For more information, see http://en.wikipedia.org/wiki/Whitebox_testing

Dependency Injection

Dependency injection aims to solve a particular problem in designing and constructing data structures dependent on other pieces of code, in a way that minimizes the coupling between them.

Dependency injection aids in helping to test particular units of code, substituting in your own versions of the dependency, removing the need to test the dependent code.

For more information, see
Dependency Injection & Testable Objects
Inversion of Control Containers and the Dependency Injection pattern

Mocking

Using the Dependency Injection pattern doesn’t require the use of a mocking framework to by-pass dependencies. It’s entirely plausible to create your own implementations and pass through. This however, will require a lot of time writing the code and cause your projects to bloat. A mocking framework should provide the facility to create dependency implementations (mocks) dynamically, taking the hard work away from the unit tester. The framework also, should provide functionality to help you assert that the mocked objects are used the way you expect them to behave.

There are various mocking frameworks out in the wild, I personally have used NMock and Rhino Mock. My experience with both favours Rhino Mock for flexibility, ease of use and performance. Type.Mock seems to get a lot of high praise too.

For more information, see:
Rhino Mocks – Introduction
Rhino Mocks – Documentation

Time for a Code Walkthrough

We have a CustomerServices class that provides business functions for a Customer entity. The CustomerServices class uses a CustomerDataAccess object to persist/read information from a database. Therefore, the CustomerServices class has a dependency on the CustomerDataAcess class.

A first cut of the two classes might look like this:

public class CustomerDataAccess : ICustomerDataAccess {

        public void InsertCustomer(string name)
        {
            // long running dependency
            Thread.Sleep(10000); // 10 seconds.
        }
}

public class CustomerServices {

  public void AddCustomer(Customer customer){
            new CustomerDataAccess().InsertCustomer(customer.Name);
  }

}

As you can see when we write a unit test for the CustomerServices.AddCustomer method it will make a call to the CustomerDataAccess class and take 100 seconds to complete.

[TestMethod]
public void TestAddCustomer () {

  Customer customer = new Customer();
  customer.Name = 'Ben';

  new CustomerServices().AddCustomer(customer);

 // To verify the test worked, a database lookup would be required.

}

Now we should already have appropriate unit tests for the CustomerDataAccess.InsertCustomer() method, so in our CustomerServices tests we can remove this dependency as it has already been tested.

Let’s re-write the CustomerServices class to utilize the dependency injection pattern:

public class CustomerServices {
        private readonly ICustomerDataAccess _customerDataAccess;
        public CustomerServices() : this (new CustomerDataAccess()) {}

        // using internal prevents the constructor from being publicly
        // available to other assemblies.
        internal CustomerServices(ICustomerDataAccess customerDataAccess)
        {
            _customerDataAccess = customerDataAccess;
        }

        public void AddCustomer(Customer customer) {
             _customerDataAccess.InsertCustomer(customer.Name);
        }
}

//NOTE:  To allow our unit testing project to access the internal members of the project we’re testing, an attribute is added to the AssemblyInfo.cs file.

#if DEBUG
  [assembly: InternalsVisibleTo("CustomerServiceTests ")]
#endif

Now we have the ability to insert our own CustomerDataAccess object, we’ll create our own mock object and use it to remove the dependency – this is for illustration purposes only.

public class MockCustomerDataAccess : ICustomerDataAccess {

      private int _insertCustomerCount = 0;

      public void InsertCustomer(string name) {
            _insertCustomerCount++;
      }

      public int InsertCustomerCount {
            get { return _insertCustomerCount; }
      }
}

[TestMethod]
public void TestAddCustomerWithStaticMock() {
      Customer customer = new Customer();
      customer.Name = 'Ben';

      ICustomerDataAccess mock = new MockCustomerDataAccess();

      CustomerServices _customerServices = new CustomerServices(mock);
      _customerServices.AddCustomer(customer);

      Assert.AreEqual(1, mock.InsertCustomerCount);
}

As you can see here, creating our own mocks and keeping metrics will become tiresome and mean code bloat – especially as you might need many instances of the same interface for differing code paths etc.

Don’t worry though there is a way forward – using a mocking framework like Rhino Mocks.

[TestMethod]
public void TestAddCustomerWithDynamicMock() {
// create the Rhino mock repository
_mockRepository = new MockRepository();

// get a dynamic instance of the ICustomerDataAccess interface
_dynamicMock = (ICustomerDataAccess) _mockRepository.DynamicMock(typeof(ICustomerDataAccess));
_customerServices = new CustomerServices(_dynamicMock);

// Expect the CustomerDataAccess.InsertCustomer method to be called exactly once.
_dynamicMock.InsertCustomer(null);

LastCall.IgnoreArguments().Repeat.Once();
_mockRepository.ReplayAll();

Customer customer = new Customer();
customer.Name = ‘Ben’;
_customerServices.AddCustomer(customer);

// ensure the asserts are correct
_mockRepository.VerifyAll();
}

Using Rhino Mocks we don’t need to create hard-coded mock objects for our tests and we get built in metric checking and a whole lot more – all for free.

What to Test?

1. Any non-trivial piece of code.
2. All code is non-trivial.
3. Then again, something’s just aren’t worth your time.
4. Confused?

For every method that has some meat on it, there should be [TestMethod]s that test all execution paths.
Public properties that are just get/set would be a situation of overkill.

The VSTS code coverage tool is excellent for seeing what you’ve tested and what’s been missed.

To use the VSTS code coverage tool, open up VS 2005 and edit the selected test configuration run:

Enabling Code Coverage
Click for Full Size Image

Then select the assemblies you wish to monitor:

Select Assemblies

Then all you have to do is run your tests (but not in debug mode) for it to calculate the metrics. Once finished open up the Code Coverage Window and inspect the results.

Code Coverage Results
Click for Full Size Image

What about Integration Testing?

We can still use the VSTS unit testing framework to write integration tests. The difference though, comes from the point of view that the test methods will not substitute in mocks for the dependencies, allowing the tests to run end-to-end testing a module/function of code right through.