How to UnitTest PipelineComponents

The biztalk pipeline framework define some interfaces that allows you to unit test the component without the biztalk infrastructure:

 

Suppose you have a General Pipeline Component, that implements the method:

 

IBaseMessage ExecutePipelineComponent (

      IPipelineContext pc , IBaseMessage inMsg )

 

 

To unit test this web method we need a valid instance of IPipeLineContext, and IBaseMessage. This instances are provided ny the Biztalk engine when the component is executed inside a “real” orchestration.

 

So to implement this interfaces I’m going to use NMock:

 

IMock mockBaseMessage = new DynamicMock(typeof(IBaseMessage));

IMock mockPipelineContext =new DynamicMock(typeof(IPipelineContext));

 

And now I can execute the method using the mock instances:

 

IBaseMessage result = azService.ExecutePipelineComponent(

      (IPipelineContext)mockPipelineContext.MockInstance,

      (IBaseMessage)mockBaseMessage.MockInstance);

 

However, I’ve found that the context used by the service is not in the pipeline context, rather the IBaseMessage interface, define a MessageContext, where the service try to read and write some properties, so we have to mock the message context also

 

IMock mockBaseMessageContext =

  new DynamicMock(typeof(IBaseMessageContext));

 

To configure the mockBaseMessage to return an instance of the mockBaseMessageContext when asked for the proerty context, you have to use the SetUpResult method of the IMock interface:

 

mockBaseMessage.SetupResult("Context",

      (IBaseMessageContext)mockBaseMessageContext.MockInstance,

      new Type[]{});

 

And now we are ready to configure the mockContext to return the values we need for specific unti test. Suppose you want to return “Rido”, when the services ask the context about a property called “UserName” under a concrete schema:

 

mockBaseMessageContext.ExpectAndReturn(

      "Read", "Rido", new object[]{

      "UserName",

      "https://schemas./BizTalk2004/Eai/Context"});

 

The last thing to configure prior to get the mock infrastructure ready to use, is the MessageId property of the message, since it’s a Guid:

 

Guid messageId = Guid.NewGuid();

mockBaseMessage.SetupResult("MessageID", messageId, new Type[]{});

 

Finally here is the complete fixture

 

[TestFixture]

public class AuthorizationServiceTest

{

       IMock mockBaseMessage;

       IMock mockBaseMessageContext;

       IMock mockPipelineContext;

       SrvAutorizacion azService;

       [TestFixtureSetUp]

       public void CreateMocks()

       {

              mockBaseMessage = new DynamicMock(typeof(IBaseMessage));

              mockBaseMessageContext = new DynamicMock(typeof(IBaseMessageContext));

              mockPipelineContext = new DynamicMock(typeof(IPipelineContext));

       }

       [SetUp]

       public void InitService()

       {

              azService = new AuthorizationService();

       }

      

       [Test]

       public void Autoriza1()

       {

              mockBaseMessageContext.ExpectAndReturn(

                     "Read", "Rido", new object[]{

                     "UserName",

                     "https://schemas./BizTalk2004/Eai/Context"});

                    

              mockBaseMessage.SetupResult("Context",

                     (IBaseMessageContext)mockBaseMessageContext.MockInstance,

                     new Type[]{});

              Guid messageId = Guid.NewGuid();

              mockBaseMessage.SetupResult("MessageID", messageId, new Type[]{});

              IBaseMessage result = azService.ExecutePipelineComponent(

                     (IPipelineContext)mockPipelineContext.MockInstance,

                     (IBaseMessage)mockBaseMessage.MockInstance);

              Assert.IsNotNull(result);

              Assert.AreEqual(messageId, result.MessageID);

 

              mockBaseMessageContext.Verify();

              mockBaseMessage.Verify();

       }

}