Unit Testing, Mocking and Dependency Injection

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.

Posted in .Net, Development, Uncategorized, Unit Testing at February 18th, 2008. 5 Comments.

VS2005 – Collapse All Solution Projects

I might be a bit slow to the game here, but just in case you didn’t know, you can create a macro in VS2005 to collapse all the projects in the Solution View window. Freakin handy!

Posted in Uncategorized at August 22nd, 2007. 1 Comment.

Code Access Security Explained

Download code: Partial Trust Code Access Security – Explained

Let’s start with an over-simplified, imprecise explanation of CAS. (NOTE: this discussion assumes that all your assemblies are strong-named.) The first thing to do is explain the levels of trust. “Fully trusted” code can do whatever the user can do (which might be limited if the user is not using a Windows admin account). “No trust” code can’t do squat. Anything in between is called “partial trust.” Obviously, there are many degrees of partial trust – the code might have almost no privileges at all, or it might be able to do everything except reading the registry or something. My own, simplified, understanding is that there are three main ways of causing code to run with partial trust:

  1. If the assembly is loaded from a network share then it will run with the “LocalIntranet” permission set (by default this enforces a number of restrictions such as no registry, no file IO, limited reflection and so on).
  2. If your assembly refuses one or more permissions (eg you declare that you don’t want to be able to perform reflection) then your assembly is by definition partially trusted.
  3. You can configure your ASP.NET application to run with a particular trust level. In fact, Microsoft recommend running ASP.NET with “medium trust” if possible! This is defined in config files; “medium trust” means no registry, no reflection, no file IO outside your app’s virtual directory and a few other things).


Notice that an assembly might be fully trusted or partially trusted depending on the runtime circumstances. The assembly might be fully trusted if loaded from the C: drive, but will be partially trusted if loaded from a network share.

Next, a couple of handy definitions:

  • Caller – Code that calls other code
  • Callee – Code that is called by other code

So if method ClientMethod() calls method ServerMethod() then ClientMethod is the caller and ServerMethod is the callee.

If the calling method (the caller) is in an assembly that is running with partial trust then it is a “partially trusted caller.” In this case, if the callee’s assembly does not have the AllowPartiallyTrustedCallers (APTC) attribute then the called code will not run – regardless of the trust level of the callee’s assembly. You will get an exception.

And now for the demo. Obviously, there are many aspects to CAS; my idea is to show you a few basic ones to get you started. The demo has two strongly named assemblies: PartialTrustTest.exe and PartialTrustTestLib.dll. There is also a config file called PartialTrustTest.exe.config that is needed for one of the scenarios.

Scenario 1

Start by placing all the files together in a directory on your C: drive and running the exe. You will see a form with three buttons. They all do the same thing: they try to read the registry. The only difference is in the methods that they use to call the RegistryKey.OpenSubKey method:

  1. Read the registry (local assembly) – calls a method in the EXE
  2. Read the registry (from PartialTrustTestLib) – calls a method in the DLL (see code at bottom of email)
  3. Read the registry after asserting permission (from PartialTrustTestLib) – calls a method in the DLL that asserts the right to read the registry (I’ll explain this below, but note that it has nothing to do with the Asserts used in testing)


Click each of the buttons in turn; you should find that they all work fine. This is because both assemblies are fully trusted.

Scenario 2

To set up this scenario, follow these steps:

  1. Move the DLL to a network drive – let’s call that the U: drive and ensure you delete it from the C: drive so that we can be sure which one is being loaded!).
  2. Open PartialTrustTest.exe.config in Notepad and uncomment the line.
  3. Replace my username with yours in the href attribute.
  4. Now run the EXE.


Button 1 is still OK, but the other two buttons throw a SecurityException. This is because the DLL is now running with the LocalIntranet permission set and as such it can’t read the registry.

The APTC attribute is not relevant here because the caller is fully trusted (it is the callee that is partially trusted).

Scenario 3

This is the most interesting one. To set up this scenario, follow these steps:

  1. Delete PartialTrustTest.exe.config
  2. Move the EXE to your network drive (U: drive)
  3. Move the DLL back to your C: drive
  4. Open the .NET Framework 2.0 Configuration utility (under Administrative Tools) and add the DLL to your GAC.
  5. Now run the EXE


Note that the DLL has the APTC attribute, which it needs here because the exe is no longer running with full trust.

Button 1 fails, because the EXE is now running with the LocalIntranet permission set.

Button 2 fails. Why? The DLL is now fully trusted (it is in the GAC and it doesn’t refuse any permissions). But the EXE does not have RegistryPermission. This is an example of luring (the unprivileged EXE asks the privileged DLL to ask the .NET Framework, like a kid asking his older brother to buy beer on his behalf). To prevent this, the RegistryKey.OpenSubKey method demands that all its callers have RegistryPermission. This demand causes the CLR to do a ‘stack walk’, checking that each caller in the stack has the required permission.

Button 3 succeeds. This is because it calls a method in the DLL that ‘asserts’ RegistryPermission. Asserting a permission is like saying ‘trust me; I know what I’m doing: don’t worry if my caller(s) don’t have RegistryPermission because I have it and I promise not to do anything bad with it’.

Notice that the assertion didn’t help in scenario 2, because the DLL didn’t have RegistryPermission. Asserting a permission that you don’t have won’t get you anywhere.

To summarise:

ScenarioEXEDLLBtn 1Btn 2Btn 3
1C: driveC: driveOKOKOK
2C: driveU: driveOKFails – callee doesn’t have RegistryPermissionFails – cal doesn’t have Registry Permission
3U: driveGACFails – callee doesn’t have RegistryPermissionFails – stack walk discovers that EXE doesn’t have RegistryPermissionOK – DLL asserts RegistryPermission
4U: driveC: drive (not GAC)C: drive (not GAC)No dice – you get an exception trying invoke the DLL; I think it’s not allowed in .NET



Using CAS correctly involves ensuring that your code can’t be used maliciously. Our DLL allows partially trusted callers and one of its methods asserts RegistryPermission. Once that DLL is installed in the GAC these two settings lower the security bar considerably. Any assembly that can run on our CLR can load our DLL and use our method to read the registry. Before adding the assertion we should (a) check our method carefully to make sure it can’t be used maliciously, and/or (b) apply extra restrictions to our method. The easiest way to restrict the method is to add a Demand to the method. This is where we demand that the callers meet a certain requirement (not the same one that we’re asserting, obviously – if they have that then there’s no point in asserting it!)

Here are the main actions associated with permissions:

  • Assert – as explained above
  • Demand – callee demands that all callers in the call stack meet a certain requirement
  • Link Demand – callee demands that the immediate previous caller in the stack meet a certain requirement (faster than Demand, but less secure)
  • Permission Request – this is where an assembly announces up-front the permissions that it needs in order to run (or those that would be nice to have). The alternative is to wait for runtime failure (as in my demo).
  • Permission Refusal – assembly asks not be given a particular permission (because it does not need it – principle of least privilege). Refusing a permission will also make your assembly a partially trusted caller.


This article is already too long, but here’s one final point: don’t overuse Demand. For example in the demo there’s no need for our methods to demand RegistryPermission. We are calling the RegistryKey.OpenSubKey framework method, which already demands this permission. If we demand it ourselves then we are just forcing an extra stack walk that will hurt performance.

Links

The best articles I’ve found online are An Introduction to Code Access Security and Code Access Security in Practice.

Remember to remove the DLL from the GAC when you’re done.

Hope this helps. And have I got it right? Please let me know.

Code for button #2:




  public static void TestRegistryAccess()
  {
      RegistryKey test = Registry.LocalMachine;
      test.OpenSubKey("Software", true);
  }


Code for button #3:




  [RegistryPermission(SecurityAction.Assert,
                             Unrestricted=true)]
  public static void AssertRegistryPermissionAndTestAccess()
  {
      RegistryKey test = Registry.LocalMachine;
      test.OpenSubKey("Software", true);
  }


Download code: Partial Trust Code Access Security – Explained

Posted in Uncategorized at August 16th, 2007. 1 Comment.

.Net tricks I’ve learnt this week

Ever wanted to write code that you want executed while testing/debugging but didn’t want built into you production/release mode code?

Just pop the [Conditional("Debug")] attribute to your class or method and it won’t get compiled into your release version.

Nice and simple!

Also, do you get sick of debugging through superflous methods (eg. dumb constructors, etc) when stepping through your code just to get to the meaty stuff that you’re really interested in?

Stick the [DebuggerStepThrough] attribute on the class, property or method you want to skip over. It’s like automatically telling the debugger to step over and not step into.

Posted in .Net, Uncategorized at August 10th, 2007. No Comments.

Skipping the Header in ItemDataBound

I often subscribe to the ItemDataBound event in a repeater to perform custom logic for each item within the repeater (for example, performing some custom calculations). When the repeater includes a header though, more often than not, you want to skip over the header row, since you don’t want to perform your custom calculations on that row. Until now, the way I did this was like this:


private void OnItemDataBound(object sender, RepeaterItemEventArgs e) {
    // skip header row
    if (e.Item.ItemIndex < 0) {
        return;
    }

    // custom logic
}

Today however, I found out there's a nicer way:


private void OnItemDataBound(object sender, RepeaterItemEventArgs e) {
    // skip header row
    if (e.Item.ItemType == ListItemType.Header) {
        return;
    }

    // custom logic
}

Sure, given that both ways work equally well, it seems as though the difference is for aesthetics only (i.e it's nicer to read); but there are actually two other big advantages:

  1. It is not tied into the implementation of the repeater - that is, it does not rely on the header row index being less than zero; and
  2. You can use the ListItemType enumeration to detect many different types of items - for example, the Footer row for performing summary calculations.

Posted in Asp.Net, Uncategorized at July 31st, 2007. No Comments.

Not Quite Quicksilver for Windows

A work colleague introduced me to Launchy and it has started to change the way that I at least stop organising the items that appear in the Start menu.

CTRL-Space is a nice little shortcut for launching new applications or documents and it’s pretty configurable so you can open up as much or as little as you want.

Give it a go!

Posted in Uncategorized at July 28th, 2007. 1 Comment.

101 ways you know your software project is doomed…

Doomed I tells ya…

Posted in Uncategorized at July 17th, 2007. No Comments.

Using SSL with IE XmlHttp request object

Recently at work we discovered that our SSL encrypted pages weren’t coming back fully encrypted. We narrowed down the partial SSL encryption problem to some default AJAX requests we were doing.

After searching the net I found that Microsofts XML Parser software must be version 3.0 with SP1 or later to support SSL.

I looked on my machine and noticed that I had MSXML 6.0 Parser.

Program Files - MSXML Parser 6.0

So it was time to look at my javascript file that instantiated the ActiveXObject.


function getXmlHttp() {
  try {
        return new ActiveXObject("Msxml2.XMLHTTP");
  } catch(e) {
    try {
      return new ActiveXObject("Microsoft.XMLHTTP");
    } catch(E) {}
  }

  if (XMLHttpRequest != "undefined") {
    return new XMLHttpRequest();
  } else {
    return null;
  }
}



Now admitedly this bit of code was copied and pasted from somewhere so it was time to finally understand exactly what was going on.

Firstly, the code tries to instantiate a version specific instance of the XmlHttp object. I’m not entirely sure which version this is bringing back but it is definitely pre-3.0 SP1.


  return new ActiveXObject("Msxml2.XMLHTTP");



If that failed to bring back an instance it tries again with the following line: -


  return new ActiveXObject("Microsoft.XMLHTTP");



This is like an factory object that will bring back the most recent version installed on the clients computer.

So to fix this problem the code was changed to: –

Firstly, the code tries to instantiate a version specific instance of the XmlHttp object. I’m not entirely sure which version this is bring back but it is definitely pre-3.0 SP1.


  try {
        return new ActiveXObject("Msxml2.XMLHTTP.6.0");
  } catch(e) {
    try {
      return new ActiveXObject("Microsoft.XMLHTTP");
    } catch(E) {}
  }

  if (XMLHttpRequest != "undefined") {
    return new XMLHttpRequest();
  } else {
    return null;
  }
}

You might think it odd that I have hard-coded an version instance as our first try, but because we’re in an intranet environment we can ensure that all clients have version 6.0 of the XML parser installed. If they don’t we’ll try our best to get a version that is hopefully later than 3.0SP1 so that we can get SSL support.

Posted in Uncategorized at July 16th, 2007. No Comments.

Creating an MD5 hashed password

Ever wondered how the FormsAuthentication.HashPasswordForStoringInConfigFile method works? Me neither, but I had to basically replicate its functionality the other day. I tried decompiling it using Reflector, but it really wasn’t any help.

The part I was struggling with was working out how to get a Hex string from a Base64 string (which is what the ComputeHash method will return to you). Turns out you need to call the ToString() method on each byte, specifying “X2″ as the format. Of course! Well, nothing illustrates a point like some code, so here it is:


/// <summary>
/// Return a Hex-string encoded validation for the nominated password
/// </summary>
public string GetHashedPassword(string password) {
    Encoding encoding = new ASCIIEncoding();
    byte[] hash = new MD5CryptoServiceProvider().ComputeHash(encoding.GetBytes(password));

    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < hash.Length; i++) {
        builder.Append(hash[i].ToString("X2"));
    }

    return builder.ToString();
}
Posted in .Net, C#, Uncategorized at July 12th, 2007. 1 Comment.

Overriding the equality operators

I’ve always found it rather painful to correctly override the equality operators in a class file. I always end up with cyclic references, stack overflows, null pointers, or other problems that are equally terrible. So finally today I sat down and figured out how to do it “correctly” – whereby “correctly” I mean, “in a way that gives me the right result without throwing an exception.

My model here is a very simple class called SimpleResponse. The class is generic (must be a primitive type, i.e. struct) and only has two fields: Value (of type T), and Description (of type String). Here’s how I did the equality overloads:


// Instance method
override public bool Equals(object obj) {
    return Equals(this, obj as SimpleResponse<T>);
}

static public bool operator ==(SimpleResponse<T> first, SimpleResponse<T> second)
{
    return Equals(first, second);
}

static public bool operator !=(SimpleResponse<T> first, SimpleResponse<T> second)
{
    return !Equals(first, second);
}

static public bool Equals(SimpleResponse<T> first, SimpleResponse<T> second)
{
    if (ReferenceEquals(first, null) && ReferenceEquals(second, null)) return true;
    if (ReferenceEquals(first, null) || ReferenceEquals(second, null)) return false;

    return Object.Equals(first.Value, second.Value) &&
        String.Equals(first.Description, second.Description);
}

The important things to note here are:

  1. All the equality methods effectively just delegate to the Equals method right down the bottom.
  2. Since you’re overriding the == and != operators, you cannot use these in your Equals method to calculate equality – this will cause a StackOverflowException. This includes checking for null – note that you have to use ReferenceEquals instead (which is a static method on the Object class).
  3. Similarly, you can’t use the Equals method without causing a StackOverflowException. If you need to use an Equals method, you need to explicitly state which Object implements the method you want to use -note here I’m using String.Equals for comparing the descriptions, and Object.Equals when I can’t tell the type of the variable.

If anyone has suggestions as to a way I could have done this better, I’d love to hear them!

Posted in .Net, C#, Uncategorized at July 6th, 2007. 2 Comments.
Quickduck logo