Testing

Rhino Mocks Callbacks

Rhino Mocks Callbacks are what I have been trying to find for 2 days!

My problem is that I needed to test the internals of a method by checking to see that a value had been evaluated properly.  The result of this operation gets passed to my DAL to be inserted into my DB.  My test was to test my Business Layer so I needed to mock the DAL to prevent the DB hit from occurring.  The problem was, how could I grab the value from inside my BL method?

With Rhino Mocks, I mocked my DAL and recoreded an Expect on the method that does the DB insert.  Now all I needed to do was to replace the default implementation of my DAL method with one used for testing.  The internals of the testing method would be able to read the params being passed to the DAL from the BL, thus allowing me to verify that the BL evaluated what it was supposed to properly before passing the data on to be inserted.

Rhino Mocks Callbacks to the rescue!  I love the power of delegates, unfortunately it’s still the largest concept that repeatedly trips me up.  After locating this post on using Rhino Mocks Callbacks, I was finally able to accomplish my goal.

The application in the example below is a WCF service which accepts TFS Notification messages when a WorkItem changes.  When I recieve the notification from TFS, I am logging the message in a log table.  One of the params that is sent from TFS contains the publisher’s url in an XML string.  My BL needs to select the value of the attribute containing this url and insert it into a column in my table.  Thus, what I wanted to test was that my xpath is correct (and if TFS changes something in subsequent versions I’ll know immediately that they changed an expected format).

WCF Method to receive the TFS notification:

public void Notify(string eventXml, string tfsIdentityXml, SubscriptionInfo subscriptionInfo)
        {
            XmlDocument eventXmlDoc = new XmlDocument();
            XmlDocument tfsIdentityXmlDoc = new XmlDocument();
            try
            {
                eventXmlDoc.LoadXml(eventXml);
                tfsIdentityXmlDoc.LoadXml(tfsIdentityXml);
                TfsNotificationDto tfsNotificationDto = new TfsNotificationDto
                    {
                        Message = eventXml,
                        Date = DateTime.Now,
                        Publisher = tfsIdentityXmlDoc.SelectSingleNode("TeamFoundationServer").Attributes["url"].Value,
                        Subscriber = "",
                        Success = 'F'
                    };
                this._repo.LogTfsNotification(tfsNotificationDto);               
            }
            catch (Exception)
            {
                throw;
            }            
        }

Test method utilizing Rhino Mocks to mock the DAL:

[Test]
        public void TestLogTfsNotification()
        {
            string pub = string.Empty;
            With.Mocks(delegate
            {
                IRepository repo = Mocker.Current.StrictMock<IRepository>();
                TfsNotificationDto tfsNotificationDto = RepositoryTests.MockTfsNotificationDto;
                Expect.Call(() => repo.LogTfsNotification(tfsNotificationDto)).Callback(new Delegates.Function<bool, TfsNotificationDto>(notification => { pub = notification.Publisher; return true;}));
                Mocker.Current.ReplayAll();
                ITfsEventService service = new TfsEventService(repo);
                service.Notify(eventXml, tfsIdentityXml, subscriptionInfo);
            });           
            Assert.AreEqual(this.publisher, pub);
        }

What I can now do is in the LogTfsNotification method of the mocked repo, I can now read the parameter passed to it from the service.Notify method.  Service.Notify is extracting the subscriber url and packages it up into a TfsNoficationDto that is passed to LogTfsNotification.  Thus I can do notification.Publisher to see what value was extracted from the xml in the service object of my BL.

Tags: , , , , , , , , , ,

Working with Streams

Since I can never remember how to work with Streams, here’s an example of reading and writing to a memory stream.

[TestMethod]
        public void GetPostTEDDelimted_Test()
        {
            DateTime startDate = DateTime.Parse("01/01/1900");
            DateTime endDate = DateTime.Parse("01/01/1900");

            IList<string> postTEDData = this.businessFacade.GetData();

            Assert.AreEqual(102, postTEDData.Count);

            System.IO.MemoryStream ms = null;
            System.IO.TextWriter writer = null;
            System.IO.TextReader reader = null;
            LumenWorks.Framework.IO.Csv.CsvReader csvReader = null;
            int counter = 0;

            try
            {
                ms = new System.IO.MemoryStream();
                writer = new System.IO.StreamWriter(ms);
                reader = new System.IO.StreamReader(ms);

                foreach (string record in postTEDData)
                {
                    writer.WriteLine(record);
                }
                writer.Flush();
                ms.Seek(0, System.IO.SeekOrigin.Begin);

                csvReader = new LumenWorks.Framework.IO.Csv.CsvReader(reader, false, ',');
                while (csvReader.ReadNextRecord())
                {
                    counter++;
                }
            }
            finally
            {
                if (writer != null) writer.Close();
                if (reader != null) reader.Close();
                if (ms != null) ms.Close();
            }

            Assert.AreEqual(102, counter);
            Assert.AreEqual(100, csvReader.FieldCount);

        }

Tags: , , , ,

Tuesday, August 25th, 2009 Programming, Software Development, Testing No Comments