Fellow BizTalk developer Bram Veldhoen was kind enough to send me some suggestions
for a future version of my PipelineTesting library,
as well as with a question that could point to a potential bug in the library.

The problem basically revolves around consuming a stream returned by the XML Assembler
component in a send pipeline when testing under a library. What Bram noticed was that
executing the pipeline would seem to work, but trying to read the body part stream
of the output message would fail with a ComException with error code 0x8004005
(E_FAIL)
.

I was fairly confident this should’ve been working, based on my own use of the library,
but I sat down to test it just to make sure. What I discovered was that indeed this
can happen if the pipeline context for the test is not aware of the schema for the
message being processed by the pipeline.

I added a new test to the library to make sure this was working correctly:

[Test]

public void CanReadXmlAssemblerStream() {

   SendPipelineWrapper pipeline = Pipelines.Xml.Send()

      .WithSpec<Schema3_FF>();

   IBaseMessage input = MessageHelper.CreateFromStream(

      DocLoader.LoadStream("CSV_XML_SendInput.xml")

      );

   IBaseMessage output = pipeline.Execute(input);

   Assert.IsNotNull(output);

   // doc should load fine

   XmlDocument doc = new XmlDocument();

   doc.Load(output.BodyPart.Data);

   XmlNodeList fields = doc.SelectNodes("//*[local-name()='Field3']");

   Assert.Greater(fields.Count, 0);

}

There are a few things to keep in mind about this issue:

  1. If you’re using the XML Assembler, make sure your pipeline context has all the necessary
    schemas. There are three ways you can do this, depending on how you are creating the
    pipeline:

    1. If you’re using the original raw API, you can use the AddDocSpec() method
      of the SendPipelineWrapper class.
    2. If you’re using the new, simple API, you can add the schema through the WithSpec() method,
      which is what the test above does.
    3. If you’re using the simple API, but you’re dynamically creating the pipeline, you
      can just add the schemas directly in the XmlAssembler configuration using the WithDocumentSpec() and WithEnvelopeSpec() methods
      (see the XmlAssembler.cs file for details).
  2. Make sure you’re testing the right thing. Sometimes, it’s enough to make sure that
    the pipeline can be executed successfully. Remember, however, that pipelines are streaming
    beasts, so a lot of the work will oftentimes happen just when you read the resulting
    stream, thus causing the processing to happen.

    This is exactly the scenario we’re seeing here today.

The second point is really important, but, for some reason, I never put much emphasis
in it when creating the library and when talking about it. I think this is important
enough to warrant doing something about it.

For starters, I’ve committed a few changes to the PipelineTesting
repository
. Besides adding the test above, I’ve also added a few ConsumeStream() and ReadString() helper
methods to the MessageHelper class to make it easier to validate your
components work by simply reading the entire stream from a message. I’ll add a few
other helper methods for this later on, but the idea is to make it so that you can
write less code for your tests.

technorati BizTalk, PipelineTesting