This project is read-only.

Mocking with Messaging Content

These examples apply if your messaging activities use messaging content.

Service Contract Name

Most of the time all of the activities in your service will use the same service contract name so you can declare a field with the contract name in the test class
private readonly XName serviceContractName = XName.Get("{http://tempuri.org/}IService");

Mocking Message Content with One Receive/Send

To demonstrate how to do this, we will unit test the default WorkflowService implementation operation GetData which accepts an int and returns the int in a string form as message content.
Because this WorkflowService contains only a single Send/Receive testing it is very simple
[TestMethod]
[DeploymentItem(@"MockingMessagingActivities.Tests\Service1.xamlx", "MockingMessagingActivities")]
public void CanMockReceiveAndSendReply()
{
    // Arrange
    const int Expected = 123;
    var xamlInjector = new XamlInjector(@"MockingMessagingActivities\Service1.xamlx");

    // Setup the XamlInjector to replace the receive / send activities
    xamlInjector.ReplaceAll(typeof(Receive), typeof(ReceiveStub));
    xamlInjector.ReplaceAll(typeof(SendReply), typeof(SendReplyStub));

    // Access the workflow service Body activity for testing with WorkflowInvoker
    var host = WorkflowInvokerTest.Create(xamlInjector.GetWorkflowService().Body);

    // Setup the extension
    var stubExtension = new MessagingStubExtension();
    stubExtension.EnqueueReceive(this.serviceContractName, "GetData", Expected);
    host.Extensions.Add(stubExtension);

    try
    {
        host.TestActivity();

        // The reply should be "123"
        Assert.AreEqual(Expected.ToString(), stubExtension.SentMessages[0].Content);
    }
    finally
    {
        host.Tracking.Trace();
    }
}

Mocking Message Content with More than One Receive/Send

Many WorkflowServices have more than one Receive/Send episode. When testing with mock Receive/Send activities you can setup multiple message values by simply passing them in order to the constructor.

Given
  • The default WorkflowService implementation GetData
  • A second method GetData2 which continues the workflow, adds 2 to the data and returns a string
When
  • The service is invoked using mocked Send/Receive with a value of 5 sent to the first receive and a value of 6 to the second receive
Then
  • The first reply is "5"
  • The second reply is "8"
[TestMethod]
[DeploymentItem(@"MockingMessagingActivities.Tests\Service2.xamlx", "MockingMessagingActivities")]
public void CanMockTwoReceiveAndSendReply()
{
    // Arrange
    var xamlInjector = new XamlInjector(@"MockingMessagingActivities\Service2.xamlx");

    // Setup the XamlInjector to replace the receive / send activities
    xamlInjector.ReplaceAll(typeof(Receive), typeof(ReceiveStub));
    xamlInjector.ReplaceAll(typeof(SendReply), typeof(SendReplyStub));

    // Access the workflow service Body activity for testing with WorkflowInvoker
    var host = WorkflowInvokerTest.Create(xamlInjector.GetWorkflowService().Body);

    // Setup the extension
    var stubExtension = new MessagingStubExtension();
    stubExtension.EnqueueReceive(this.serviceContractName, "GetData", 5);
    stubExtension.EnqueueReceive(this.serviceContractName, "GetData2", 6);
    host.Extensions.Add(stubExtension);

    try
    {
        host.TestActivity();

        // Assert
        // The first reply is "5"
        Assert.AreEqual("5", stubExtension.SentMessages[0].Content);

        // The second reply is "8"
        Assert.AreEqual("8", stubExtension.SentMessages[1].Content);
    }
    finally
    {
        host.Tracking.Trace();
    }
}

Last edited Nov 12, 2011 at 9:39 PM by ronjacobs, version 3

Comments

No comments yet.