Thursday, July 23, 2009

Create a Test Dataset for Unit Testing

Here is a way to set up a test dataset for unit testing using an embedded text file as the test data source, so that the unit tests are not made brittle by having to rely on a database connection.

First I added a new folder TestData to my UnitTest project.  In that folder, I created a tab-delimited TestDataset.txt file with a header row, then I set the Properties for TestDataset.txt so that Build Action = Embedded Resource.

Then I created an internal class TestDataset.cs in my UnitTest project to read the TestDataset.txt file.  The class constructor reads the text file into a private List<string[]>, which can then be used to populate BEL objects.  This class can be instantiated in the NUnit [TestFixtureSetUp] method. Here is the code:

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Reflection;
  4: using System.IO;
  5: using System.Collections.ObjectModel;
  6: using Rhino.Mocks;
  7: 
  8: namespace TNC.ConProDataSync.Synchronize.UnitTests.TestData
  9: {
 10:     /// <summary>
 11:     /// Generates a test dataset.  Instantiate in a TestFixtureSetUp. 
 12:     /// </summary>
 13:     internal class TestDataset
 14:     {
 15:         private List<string[]> _testDataset;
 16:         
 17:         /// <summary>
 18:         /// Constructor reads the test dataset from the embedded resource text file
 19:         /// </summary>
 20:         internal TestDataset()
 21:         {
 22:             _testDataset = GetTestDataset(Assembly.GetExecutingAssembly());
 23:         }
 24: 
 25:         /// <summary>
 26:         /// Number of datarows in the test dataset
 27:         /// </summary>
 28:         internal int NumberTestRecords { get { return _testDataset.Count; } }
 29: 
 30:         /// <summary>
 31:         /// Test dataset of populated BEL objects
 32:         /// </summary>
 33:         internal Collection<MyBel> TestDataset()
 34:         {
 35:             Collection<MyBel> dataset = new Collection<MyBel>();
 36:             foreach (string[] datarow in _testDataset)
 37:             {
 38:                 MyBel bel = MockRepository.GenerateStub<MyBel>();
 39:                 bel.Prop0 = datarow[0];
 40:                 bel.Prop1 = datarow[1];
 41:                 // etc.
 42:                 dataset.Add(bel);
 43:             }
 44:             return dataset;
 45:         }
 46: 
 47:         /// <summary>
 48:         /// Reads the test dataset from the embedded text resource file
 49:         /// </summary>
 50:         /// <param name="asm">Executing assembly</param>
 51:         /// <returns>List of string arrays populated with test data</param>
 52:         private static List<string[]> GetTestDataset(Assembly asm)
 53:         {
 54:             List<string[]> dataset = new List<string[]>();
 55:             int lineCount = 0;
 56:             try
 57:             {
 58:                 // read the datarows from the TestDataset file, skipping the 1st header line
 59:                 using (Stream strm = asm.GetManifestResourceStream(TestDatasetEmbeddedResourceName(asm)))
 60:                 {
 61:                     using (StreamReader reader = new StreamReader(strm))
 62:                     {
 63:                         while (reader.Peek() >= 0)
 64:                         {
 65:                             lineCount++;
 66:                             string dataline = reader.ReadLine();
 67:                             if (lineCount > 1)
 68:                             {
 69:                                 // each line in the text file is tab-delimited
 70:                                 string[] datarow = dataline.Split(char.Parse(char.ConvertFromUtf32(9)));
 71:                                 dataset.Add(datarow);
 72:                             }
 73:                         }
 74:                     }
 75:                 }
 76:             }
 77:             catch { throw; }
 78:             return dataset;
 79:         }
 80: 
 81:         /// <summary>
 82:         /// Fully-qualified name of the embedded test dataset text file
 83:         /// </summary>
 84:         /// <param name="asm">Executing assembly</param>
 85:         private static string TestDatasetEmbeddedResourceName(Assembly asm)
 86:         {
 87:             return asm.GetName().Name + ".TestData.TestDataset.txt";
 88:         }
 89:     }
 90: }

No comments:

Post a Comment