Geeks With Blogs
Blog Moved to http://podwysocki.codebetter.com/ Blog Moved to http://podwysocki.codebetter.com/

Lately a lot of my work has focused on BizTalk for some custom solutions.  I'm a big fan of BizUnit as a unit testing tool for BizTalk, as it is pretty much the only option.  But, what happens when you call custom components (dlls) through Expression or Message Assignment Shapes?

Take for example this custom code snippet

public class OrchestrationHelper
{
     public static void ProcessDocument(XLANGMessage bizTalkMessage)
     {
          Stream bizTalkStream = (Stream)bizTalkMessage[0].RetrieveAs(typeof(Stream));

          // Do Stuff
     }
}

Instead, we should try to abstract the XLANGMessage as much as possible since there are many common operations we might do with it.  Let's define an interface with most of the operations I would do with a XLANGMessage or XLANGPart class.

public interface IOrchestrationMessage
{
     object GetPropertyValue(Type propType);

     void SetPropertyValue(Type propType, object value);

     Stream RetrieveAsStream(int partIndex);

     XmlDocument RetrieveAsXmlDocument(int partIndex);

     XmlReader RetrieveAsXmlReader(int partIndex);

     void LoadFrom(int partIndex, Stream stream);

     void LoadFrom(int partIndex, XmlDocument document);

     void LoadFrom(int partIndex, XmlReader reader);
}

From there I can abstract the XLANGPart and XLANGMessage pieces that I need on a regular basis so that I can get all the context variables and message parts without having the complex object.

Then I would implement something like this:

public class BizTalkOrchestrationMessage : IOrchestrationMessage
{
     ...
}

I use this interface for mocks.  Let's go ahead and fill out the capabilities with our Orchestration Helper class:

public class OrchestrationHelper
{
     public static void ProcessDocument(XLANGMessage bizTalkMessage)
     {
          IOrchestrationMessage message = new BizTalkOrchestrationMessage(bizTalkMessage);
          DocumentProcessor.ProcessMessage(message);
     }
}

public class DocumentProcessor
{
     public static void ProcessMessage(IOrchestrationMessage message)
     {
          // Do stuff
          string MessageID = message.GetPropertyValue(typeof(BTS.MessageID));

          ....
     }
}

I prefer Rhino Mocks at the moment for my mocking capabilities  Let's show a sample test using this framework:

[Test]
[ExceptedException(typeof(DocumentInvalidException))]
public void ProcessMessage_Success()
{
     MockRepository mocks = new MockRepository();
     IOrchestrationMessage btsMessage = mocks.CreateMock<IOrchestrationMessage>();

     Expect.On(btsMessage).Call(btsMessage.GetPropertyValue(typeof(BTS,MessageID))).Return(Guid.NewGuid());
     mocks.ReplayAll();

     DocumentProcessor.ProcessMessage(btsMessage);

     // Rest of test goes here
}

So, by abstracting the XLANGMessage and XLANGPart away from the orchestration helper classes, this helps me use mocks for my test driven development.  I'd rather not use mocks on the XLANGMessage itself.  So, as you can see, TDD can really be applied at all layers of any BizTalk solution.

 

kick it on DotNetKicks.com

Posted on Tuesday, November 20, 2007 10:18 AM Microsoft , BizTalk , .NET , Test Driven Development | Back to top


Comments on this post: TDD and BizTalk Orchestration Expression Code

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Matthew Podwysocki | Powered by: GeeksWithBlogs.net