Sunday, April 22, 2012

XLANGMessage mockup

If you pass Microsoft.XLANG.BaseType.XLANGMessage to a helper function from an orchestration, you probably need a mockup version of the XLANGMessage, I do not want to run the whole orchestration to test out my helper functions. I google and i found a blogpost by Mark describing how to do this.
http://biztalk-dev.blogspot.se/2009/06/unit-testing-with-xlangmessage.html

The main thing is that the class XLANGMessage is abstract and can't be instantiated, we need to make an implementation of it. Mark has mocked the basics of an concrete class that derives from XLANGMessage.

Here is a copy of Marks classes, I have also included an example where i used XSD.exe to create a serializble class of a customer message ASCC_CONTAINER. Please don't ask for ASCC_CONTAINER it's not mine to give.

My helper class need to use message.RetrieveAs(typfo(XMLDocument) conversion which I have implemented in the mockup.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.XLANGs.BaseTypes;
using System.Xml;
using System.IO;
using BiztalkHelper.UnpackBase64.Component;
using System.Xml.Serialization;

namespace BTHelperTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //Sample message
            FileStream sf = new FileStream(@"..\..\Sample\2a5e4eed-52c5-4fb6-8a1a-dadbd678bc1a.xml",FileMode.Open,FileAccess.Read);
            System.Xml.Serialization.XmlSerializer serializer = new XmlSerializer(typeof(ASCC_CONTAINER));
            ASCC_CONTAINER msg = (ASCC_CONTAINER)serializer.Deserialize(sf);

            //Create mockup with sample message
            MockXLANGMessage<ASCC_CONTAINER> ContainerMsg = new MockXLANGMessage<ASCC_CONTAINER>(msg);

            // Test Biztalk helper library
            unpackMessage objUnpack = new unpackMessage();
            XmlDocument retXML = objUnpack.unpackBase64(ContainerMsg);
        }
    }


    public class MockXLANGPart<T> : XLANGPart
    {
        T m_obj;

        public MockXLANGPart(T obj)
        {
            m_obj = obj;
        }

        public override void Dispose()
        {
        }

        public override object GetPartProperty(Type propType)
        {
            throw new NotImplementedException();
        }

        public override Type GetPartType()
        {
            throw new NotImplementedException();
        }

        public override string GetXPathValue(string xpath)
        {
            throw new NotImplementedException();
        }

        public override void LoadFrom(object source)
        {
            throw new NotImplementedException();
        }

        public override string Name
        {
            get { return "MockXLANGPart"; }
        }

        public override void PrefetchXPathValue(string xpath)
        {
            throw new NotImplementedException();
        }

        public override object RetrieveAs(Type t)
        {
            if (t == typeof(T))
            {
                return m_obj;
            }

            if (t == typeof(XmlDocument))
            {
                XmlSerializer serial = new XmlSerializer(typeof(T));
                MemoryStream memStream = new MemoryStream();
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memStream, Encoding.UTF8);
                serial.Serialize(xmlTextWriter, m_obj);
                memStream.Seek(0, System.IO.SeekOrigin.Begin);
                XmlTextReader textReader = new XmlTextReader(memStream);
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(textReader);
                return xmlDoc;
            }
            return null;
        }

        public override void SetPartProperty(Type propType, object value)
        {
            throw new NotImplementedException();
        }

        public override System.Xml.Schema.XmlSchema XmlSchema
        {
            get { throw new NotImplementedException(); }
        }

        public override System.Xml.Schema.XmlSchemaCollection XmlSchemaCollection
        {
            get { throw new NotImplementedException(); }
        }
    }

    public class MockXLANGMessage<T> : XLANGMessage
    {
        List<MockXLANGPart<T>> m_parts = new List<MockXLANGPart<T>>();

        public MockXLANGMessage(T obj)
        {
            m_parts.Add(new MockXLANGPart<T>(obj));
        }

        public override void AddPart(object part, string partName)
        {
            throw new NotImplementedException();
        }

        public override void AddPart(XLANGPart part, string partName)
        {
            throw new NotImplementedException();
        }

        public override void AddPart(XLANGPart part)
        {
            throw new NotImplementedException();
        }

        public override int Count
        {
            get { return m_parts.Count; }
        }

        public override void Dispose()
        {
        }

        public override System.Collections.IEnumerator GetEnumerator()
        {
            return m_parts.GetEnumerator();
        }

        public override object GetPropertyValue(Type propType)
        {
            throw new NotImplementedException();
        }

        public override string Name
        {
            get { return "MockXLANGMessage"; }
        }

        public override void SetPropertyValue(Type propType, object value)
        {
            throw new NotImplementedException();
        }

        public override XLANGPart this[int partIndex]
        {
            get { return m_parts[partIndex]; }
        }

        public override XLANGPart this[string partName]
        {
            get { return m_parts[0]; }
        }
    }
}


Many thanx to Mark for pointing me in the right direction.