RJP Software Blog

.Net info and code snippets

Archive for the ‘Unit Testing’ Category

Reading and Listing Embedded Files

without comments

When writing unit tests I occasionally find the need to include embedded resources (mostly files – e.g. XML). This enables the tests to run anywhere without relying on a specific file structure. Each time I do this I seem to have to re-create the same test utility for managing these files so I thought I’d pop the code on my blog:

Here is some sample code:

public class EmbededResourceHelper
{
	public static string ReadEmbededResourceFile(string path)
	{
		var text = string.Empty;
		using (var stream = Assembly.GetExecutingAssembly()
                          .GetManifestResourceStream(path))
		using (var reader = new StreamReader(stream))
		{
			text = reader.ReadToEnd();
			reader.Close();
		}

		return text;
	}

	public static byte[] ReadEmbededResourceFileAsBytes(string path)
	{
		byte[] bytes;
		using (var stream = Assembly.GetExecutingAssembly()
                            .GetManifestResourceStream(path))
		{
			bytes = ReadFully(stream);
		}

		return bytes;
	}

	private static byte[] ReadFully(Stream input)
	{
		byte[] buffer = new byte[16 * 1024];
		using (var ms = new MemoryStream())
		{
			int read;
			while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
			{
				ms.Write(buffer, 0, read);
			}
			return ms.ToArray();
		}
	}

	public static void ListEmbededResources()
	{
		Assembly.GetExecutingAssembly()
                   .GetManifestResourceNames().ToList()
                      .ForEach(x => Debug.WriteLine(x));
	}
}

Written by Rich

February 8th, 2012 at 5:19 pm

Posted in Unit Testing

NMock – Custom List Matcher

without comments

I am a big believer in Test Driven development. I am also an avid user of mocking Frameworks I having used the excellent Rhino Mocks framework in the past and am currently using the NMock framework as this is the preference of my current client.

Anyway, the other day I was testing some code was struggling to work out how to test it effectively. The code that I was trying to test is shown below:

   public interface IDataGateway
   {
      int AddMessageToQueue(Message message, IList customerIds);
   }

   public class MessageHandler
   {
      private IDataGateway _dataGateway;
      public MessageHandler(IDataGateway dataGateway)
      {
         _dataGateway = dataGateway;
      }

      public int SendMessage(Message message, IList customerIds)
      {
         IList newCustomerIds = customerIds.ToList().ConvertAll(c => int.Parse(c));
         int messageCount = _dataGateway.AddMessageToQueue(message, newCustomerIds);
         return messageCount;
      }
   }

The code above is fairly simple. I won’t discuss ways to improve it as it is really designed to illustrate a point.

As I am a Mockist I would like to test that given an input message and list of customer ids the AddMessageToQueue method on the _dataGateway object is called with the correct parameters.

NMock can help me with this because it allows me to Mock the _dataGateway interface and then inspect the interactions between my MessageHandler object and _dataGateway. The problem is that I can’t test this interaction in the bog standard NMock way because my I have no control over the newCustomerIds list that is created inside this method. Enter the Custom Matcher.

So, I developed a custom list matcher and used this to help define the expectation on the _dataGateway mock. The code is listed below:

   public class ListMatcher : Matcher
   {
      private IList _theList;

      public ListMatcher() : this(null)
      {
      }

      public ListMatcher(IList theList)
      {
         _theList = theList;
      }

      public override void DescribeTo(System.IO.TextWriter writer)
      {
         writer.Write("< ");
         writer.Write(this.GetType().Name);
         writer.Write(">");
      }

      public override bool Matches(object o)
      {
         bool itMatches = false;
         List inList = o as List;
         if ((inList != null) && inList.Count == _theList.Count)
         {
            itMatches = true;
            for (int i = 0; i < _theList.Count; i++)
            {
               itMatches = itMatches && _theList[i].ToString() == inList[i].ToString();
            }
         }

         return itMatches;
      }
   }

This list matcher allows NMock to compare the elements of two lists. You pass the expected list into the constructor on instantiation and this is used to compare against a list passed in a method call.

The code snippet below shows how to wire up the unit test.

   [Test]
   public void SendMessage_ExpectCorrectInteractions()
   {
      Mockery mockery = new Mockery();
      IDataGateway dataGateway = mockery.NewMock();

      MessageHandler handler = new MessageHandler(dataGateway);

      Message message = new Message();
      List customerIds = new List(new string[] { "1", "2", "3" });
      List expectedCustomerIds = new List(new int[] { 1, 2, 3 });

      Expect.Once.On(dataGateway).Method("AddMessageToQueue").
		With(Is.EqualTo(message), new ListMatcher(expectedCustomerIds)).Will(Return.Value(6));

      handler.SendMessage(message, customerIds);  

	  mockery.VerifyAllExpectationsHaveBeenMet();
   }

That's it really, hope that this proves useful to somebody!

Written by Rich

March 10th, 2010 at 1:23 pm

Posted in Unit Testing