My Adventures in Coding

September 19, 2009

Validating Xml with a Schema in an NUnit Test (.NET 3.5/C#)

Filed under: .NET,c# — Brian @ 2:19 pm
Tags: , ,

Recently we decided to make some updates to our web app. The front end website is in ASP.NET/C#, while the back end is all in Java and using REST APIs as the interface. One pair of programmers was assigned the task of updating the web app and the other pair was assigned the task of writing the new REST service used by the web app. To ensure that both sides would be able to talk to each other when completed, we wrote an XML Schema to act as our contract and placed it in an SVN external available to both projects.

In our functional test for the REST client side code (.NET/C#) we used a stub from which we could grab the XML being sent. To test that this XML conformed to the schema (contract) we agreed to, we created the following helper class:

Xml Validator Helper Class

using System;
using System.Xml;
using System.Xml.Schema;
using System.IO;

namespace Test.Helper
{
	public class XmlValidatorTestHelper
	{
		private bool isValidXml = true;
		private string validationError = "";

		public String ValidationError
		{
			get { return "Validation Error: " + validationError; }
			set { validationError = value; }
		}

		public bool IsValidXml
		{
			get { return isValidXml; }
		}

		/// 
		/// Validate an xml document against an xml schema.
		/// 
		public void ValidXmlDoc(XmlDocument xmlDocument, XmlSchema xmlSchema)
		{
			validateParameters(xmlDocument, xmlSchema);
			XmlReader xmlReader = createXmlReader(xmlDocument, xmlSchema);
					
			try
			{
				// validate        
				using (xmlReader)
				{
					while (xmlReader.Read())
					{}
				}
				isValidXml = true;
			}
			catch (Exception ex)
			{
				ValidationError = ex.Message;
				isValidXml = false;
			}
		}

		private static void validateParameters(XmlDocument xmlDocument, XmlSchema xmlSchema)
		{
			if (xmlDocument == null)
			{
				new ArgumentNullException("ValidXmlDoc() - Argument NULL: XmlDocument");
			}
			if (xmlSchema == null)
			{
				new ArgumentNullException("ValidXmlDoc() - Argument NULL: XmlSchema");
			}
		}

		private static XmlReader createXmlReader(XmlDocument xmlDocument, XmlSchema xmlSchema)
		{
			StringReader xmlStringReader = convertXmlDocumentToStringReader(xmlDocument);
			XmlReaderSettings xmlReaderSettings = new XmlReaderSettings 
                        { 
                               ValidationType = ValidationType.Schema 
                        };
			xmlReaderSettings.Schemas.Add(xmlSchema);
			return XmlReader.Create(xmlStringReader, xmlReaderSettings);
		}

		private static StringReader convertXmlDocumentToStringReader(XmlDocument xmlDocument)
		{
			StringWriter sw = new StringWriter();
			xmlDocument.WriteTo(new XmlTextWriter(sw));
			return new StringReader(sw.ToString());
		}
	}
}

Surfacing Validation Errors in your Test

Finding out that the XML our REST client produces matches the contract is great, however when it fails it would save a lot of time if the test just showed WHY validation failed. No problem, in our validation helper class we added a property to allow us to retrieve the validation error message in the event the test failed and output that as the failure message for the test:

XmlValidatorTestHelper xmlSchemaValidator = new XmlValidatorTestHelper();
XmlSchema myXmlSchema = XmlSchema.Read(...);
XmlDocument myXmlDocument = new XmlDocument();
myXmlDocument .Load(...);
xmlSchemaValidator.ValidXmlDoc(myXmlDocument, myXmlSchema);

Assert.IsTrue(xmlSchemaValidator.IsValidXml, "XML does not match Schema: " + xmlSchemaValidator.ValidationError);
Advertisements

1 Comment »

  1. myXmlDocument.Schemas.Add(myXmlSchema);
    myXmlDocument.Validate((o, e) =>
    {
    if (e.Severity == XmlSeverityType.Error) Assert.Fail();
    });

    Comment by Md Shahnath Ullah — March 18, 2016 @ 6:01 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: