September 2008 Entries
TFS2008 Build features

Our upgrade from TFS2005 to TFS2008 is coming up this weekend, and there have been a number of important improvements in the TFS build system. Microsoft have been listening to some of the criticism over the way 2005 worked, and seemed to have addressed the majority of them. Here's an (non-exhaustive) list of new features:

  • Separation of build types (including CI policy, retention policy) from the build project (the .proj file)
  • Inclusion of automated builds
  • Unit testing without the VSMDI
  • Build retention policies
  • Build queuing
  • Improved control over builds in the VS2008 GUI

Whilst none of these new features are hugely exciting, they represent the kind of fine grained polish that's been much needed on the build front for a while now, and should make working with builds in TFS a little easier.

Buck Hodges has an excellent collection of links (note: these cover Beta 2, so some of the detail may be incorrect, but the overall thrust is accurate) that go into far more detail then I've got the time to do here. Well worth a read if you're involved in the build process on your team, or you're just interested in how things have moved along.

Using two test frameworks - NUnit & MSTest

Following on from Neil's post about switching between unit test frameworks, I was hitting some problems with his described method. The answer (for me at least, your mileage may vary) was to change around the using block to :

   1:  #if NUNIT
   2:  using NUnit.Framework;
   3:  using TestClass = NUnit.Framework.TestFixtureAttribute;
   4:  using TestMethod = NUnit.Framework.TestAttribute;
   5:  using TestInitialize = NUnit.Framework.SetUpAttribute;
   6:  using TestCleanup = NUnit.Framework.TearDownAttribute;
   7:  using ClassInitialize = NUnit.Framework.TestFixtureSetUpAttribute;
   8:  using ClassCleanup = NUnit.Framework.TestFixtureTearDownAttribute;
   9:  #else
  10:  using Microsoft.VisualStudio.TestTools.UnitTesting;
  11:  #endif

The NUNIT symbol is only defined on debug builds, so I'm using NUnit to run my tests when I'm coding, and then MSTest for builds conducted during CI / Release builds. This gives me the perfect duality of fast turn around of tests whilst coding (including automatic test runs when I build) and the integration of MSTest into TFS during "proper" builds. As I'm using MSTest for release builds I can also enable code coverage (occasionally running the tests through MSTest in development to get a view of how much I've covered).

One thing to watch out for when using Rhino Mock with code coverage is a trust issue, neatly described in this blog entry.

2 Comments Filed Under [ C# ]
Rhino Mock - Same interface, different types - Revisited

Following on from yesterdays post about creating two different types from a single interface - I have my answer. In fact I've got two... one's dirty, one's clean. Thanks to Hadi for the clean answer, which is what I've gone with.

Dirty Answer

Those of a sensitive disposition may want to look away now, or at least scroll to the next paragraph, because this isn't going to be pretty. I dug into the Rhino Mock assembly looking for the point where, maybe, I'd be able to switch the default behaviour to want I wanted. In my quest I found this method on MockRepository:

   1:  protected virtual ProxyGenerator GetProxyGenerator(Type type)
   2:  {
   3:      if (!generatorMap.ContainsKey(type))
   4:      {
   5:          generatorMap[type] = new ProxyGenerator();
   6:      }
   7:      return generatorMap[type];
   8:  }

"Oh yes!" thinks I. All I have to do is inherit MockRepository as MultiTypeMockRepository, override GetProxyGenerator and then always return a new ProxyGenerator. Alas, this was not to be, somehow the people behind Rhino have managed to expose an internal type (ProxyGenerator) as a return value on a protected method of a public class. For a brief moment I contemplated grabbing the Rhino source and rolling my own, but the overhead for a few simple tests wasn't worth it. Finding this method had exposed to me the cache of ProxyGenerators that Rhino are using. My next line of thought was to use reflection to tinker with the innards of MockRepository (told you this was the dirty answer):

   1:     public static class MyMockRepository
   2:     {
   3:        public static void FlushProxyGenerators()
   4:        {
   5:           Type mrType = typeof(MockRepository);
   6:   
   7:           FieldInfo generatorMapField = mrType.GetField("generatorMap", BindingFlags.NonPublic | BindingFlags.Static);
   8:   
   9:           object generatorMap = generatorMapField.GetValue(null);
  10:   
  11:           lock (generatorMap)
  12:           {
  13:              Type generatorMapType = generatorMap.GetType();
  14:              PropertyInfo keys = generatorMapType.GetProperty("Keys");
  15:              MethodInfo remove = generatorMapType.GetMethod("Remove");
  16:   
  17:              List<Type> types = new List<Type>(keys.GetValue(generatorMap, null) as IEnumerable<Type>);
  18:   
  19:              foreach (Type t in types) remove.Invoke(generatorMap, new object[] { t });
  20:           }
  21:        }
  22:     }

Guess what? It worked. Although my unit test code now had a rather odd call to FlushProxyGenerators in between the creation of the two outbound classes. That and I'd broken pretty much every rule in the book... dang.

Clean Answer

Hadi had suggested that I create a couple of stub concrete classes from my interface, set the SendMessage method as virtual and then mock from them. The resultant code looks thus:

   1:     public class MockEmailService : IOutboundService
   2:     {
   3:        #region IOutboundService Members
   4:   
   5:        public virtual void SendMessage(Dictionary<string, string> data, IEnumerable<IServicePolicy> policies)
   6:        {
   7:           throw new NotImplementedException();
   8:        }
   9:   
  10:        #endregion
  11:     }

 
   1:     public class MockFtpService : IOutboundService, IInboundService
   2:     {
   3:        #region IOutboundService Members
   4:   
   5:        public virtual void SendMessage(Dictionary<string, string> data, IEnumerable<IServicePolicy> policies)
   6:        {
   7:           throw new NotImplementedException();
   8:        }
   9:   
  10:        #endregion
  11:   
  12:        #region IInboundService Members
  13:   
  14:        public event EventHandler<OrderReceivedEventArgs> OrderReceived;
  15:   
  16:        public event EventHandler<OrderNotificationReceivedEventArgs> OrderNotificationReceived;
  17:   
  18:        public event EventHandler<OrderAssociationReceivedEventArgs> OrderAssociationReceived;
  19:   
  20:        public event EventHandler<OrderActivationReceivedEventArgs> OrderActivationReceived;
  21:   
  22:        #endregion
  23:     }

 

   1:        [TestMethod]
   2:        public void SendMessage_TwoOutbound_RoutedToTwoCorrectly()
   3:        {
   4:           IOutboundService outbound1 = _mockRepository.StrictMock<MockEmailService>();
   5:           IOutboundService outbound2 = _mockRepository.StrictMock<MockFtpService>();
   6:           ProcessOutboundRouter router = new ProcessOutboundRouter();
   7:           router.Add(outbound1);
   8:           router.Add(outbound2);
   9:   
  10:           IServicePolicy policy1 = _mockRepository.StrictMock<IServicePolicy>();
  11:           IServicePolicy policy2 = _mockRepository.StrictMock<IServicePolicy>();
  12:   
  13:           Dictionary<string, string> data = new Dictionary<string, string>();
  14:   
  15:           Expect.Call(policy1.ServiceType).Return(outbound1.GetType());
  16:           Expect.Call(delegate { outbound1.SendMessage(data, new IServicePolicy[] { policy1 }); });
  17:           Expect.Call(policy2.ServiceType).Return(outbound2.GetType());
  18:           Expect.Call(delegate { outbound2.SendMessage(data, new IServicePolicy[] { policy2 }); });
  19:   
  20:           _mockRepository.ReplayAll();
  21:           router.SendMessage(data, new IServicePolicy[] { policy1, policy2 });
  22:           _mockRepository.VerifyAll();
  23:        }

Note : I've changed the name of some of the interfaces.

Much neater in the test, and without the pangs of guilt I get when I do something really nasty.

One Comment Filed Under [ C# ]
Rhino Mock - Same interface, different types

I'm trying out Rhino mock on a new project at the moment, trying to get into the TDD groove (which, thanks to NUnit, I am). I've started my codebase with interfaces and a couple of implementations, writing my tests before the classes like a good boy. All was going well, Rhino mock proving to be adaptable and reasonably concise in its operations when I hit upon a scenario that had me stumped.

I have an ProcessOutboundRouter class that implements the interface IProcessOutbound, this router wraps up calls to a list of other IProcessOutbound instances, forwarding messages to the correct instance on the basis of policies (defined by the IServicePolicy interface). The router does this by matching the value of a ServiceType property on the policy to the type of the IProcessOutbound instance. When it came to testing I'd originally setup my test thus:

 

   1:  [Test]
   2:  public void SendMessage_TwoOutbound_RoutedToTwoCorrectly()
   3:  {
   4:     IProcessOutbound outbound1 = _mockRepository.StrictMock<IProcessOutbound>();
   5:     IProcessOutbound outbound2 = _mockRepository.StrictMock<IProcessOutbound>();
   6:     ProcessOutboundRouter router = new ProcessOutboundRouter();
   7:     router.Add(outbound1);
   8:     router.Add(outbound2);
   9:   
  10:     IServicePolicy policy1 = _mockRepository.StrictMock<IServicePolicy>();
  11:     IServicePolicy policy2 = _mockRepository.StrictMock<IServicePolicy>();
  12:   
  13:     Dictionary<string, string> data = new Dictionary<string, string>();
  14:   
  15:     Expect.Call(policy1.ServiceType).Return(outbound1.GetType());
  16:     Expect.Call(delegate { outbound1.SendMessage(data, new IServicePolicy[] { policy1 }); });
  17:     Expect.Call(policy2.ServiceType).Return(outbound2.GetType());
  18:     Expect.Call(delegate { outbound2.SendMessage(data, new IServicePolicy[] { policy2 }); });
  19:   
  20:     _mockRepository.ReplayAll();
  21:     router.SendMessage(data, new IServicePolicy[] { policy1, policy2 });
  22:     _mockRepository.VerifyAll();
  23:  }

Alas, 'twas not to be... I'd hoped that the StrictMock<T> method would return different mocks with different types when creating multiple mocks of the same interface. Understandably it doesn't, both outbound1 and outbound2 are of the same proxy type generated by Rhino mock. Creating a new MockRepository instance doesn't help either. So I've, somewhat unfortunately, ended up with the following:

 

   1:  [Test]
   2:  public void SendMessage_TwoOutbound_RoutedToTwoCorrectly()
   3:  {
   4:     IProcessOutbound outbound1 = _mockRepository.StrictMock<IProcessOutbound>();
   5:     IProcessOutbound outbound2 = _mockRepository.StrictMock<IMockProcessOutbound>();
   6:     ProcessOutboundRouter router = new ProcessOutboundRouter();
   7:     router.Add(outbound1);
   8:     router.Add(outbound2);
   9:   
  10:     IServicePolicy policy1 = _mockRepository.StrictMock<IServicePolicy>();
  11:     IServicePolicy policy2 = _mockRepository.StrictMock<IServicePolicy>();
  12:   
  13:     Dictionary<string, string> data = new Dictionary<string, string>();
  14:   
  15:     Expect.Call(policy1.ServiceType).Return(outbound1.GetType());
  16:     Expect.Call(delegate { outbound1.SendMessage(data, new IServicePolicy[] { policy1 }); });
  17:     Expect.Call(policy2.ServiceType).Return(outbound2.GetType());
  18:     Expect.Call(delegate { outbound2.SendMessage(data, new IServicePolicy[] { policy2 }); });
  19:   
  20:     _mockRepository.ReplayAll();
  21:     router.SendMessage(data, new IServicePolicy[] { policy1, policy2 });
  22:     _mockRepository.VerifyAll();
  23:  }

Notice the second IProcessOutbound instance is a mock for a different interface (IMockProcessOutbound, which merely inherits IProcessOutbound without adding anything). Whilst this works, it's nowhere near a final solution, what happens if I need a third instance (again of a different type)? Another interface? Not a good pattern.

Has anyone managed to achieve the desired effect without having to resort to the new interface trick?

One Comment Filed Under [ C# ]