This project is read-only.
Project Description
Mocking BizTalk is a set of tools aimed at bringing Mock Object concepts in BizTalk solution testing.
Actually it consists in a set of MockPipelines whose implementation is not fixed but decided at run-time compiling script files written in boo language.

Rationale
Unit testing a BizTalk solution can be a very difficult task; this is due to the fact that, being BizTalk an EAI (converging towards an ESB), solution are naturally loosely coupled and integration oriented.

The best BizTalk Unit test framework (BizUnit) is actually more an "integration" test framework because a solution is fully testable only when endpoint external systems are available and online.

To make things worse, every piece realizing the architecture (pipelines, orchestrations, maps, custom .NET dlls) usually implements a very narrow and specific task (such as promoting properties, transforming message format, doing a database lookup , etc), while following components depends on tasks realized in preceding steps, realizing therefore a dependancy chain that makes extremely difficult to test a single component in isolation from others.

How can we test an Orchestration realizing a convoy when the promoted property initializing the convoy from a still-to-be-realized pipeline component or, even worse, application on an external system ?

Mock Objects are the way OO discipline solves this specific issue: a simulated object that mimic the behavior of real objects.

According to wikipedia, aside from the reason depicted above, there are several other situations in which a mock object could be useful instead of real object:
  • when real object supplies non-deterministic results (e.g. the current time or the current temperature);
  • to test real object states that are difficult to create or reproduce (e.g. a network error);
  • when real object is slow (e.g. a complete database, which would have to be initialized before the test);
  • when real object does not yet exist or may change behavior;
  • when real object would have to include information and methods exclusively for testing purposes (and not for its actual task).

Towards Mock Pipeline Component

Being BizTalk Server an EAI/ESB its foundation is a Messaging Oriented Middleware; therefore each activity, in biztalk, is triggered by some kind of messages received from external systems:

If the external system is not ready realizing mock pipelines can be done but it’s not a quick process, it’s necessary:
  • implement the pipeline component exposing the mock behavior (that mimics the external system expected behaviour) writing C# code, implementing interfaces required (IComponent, IDisassembler or IAssembler) and compiling it in a pipeline component
  • implement a pipeline containing custom pipeline component/s realized in the above step, compiling it and deploying it in BizTalk Test Environment.

These steps requires development, compilation and deployment and, even worse, are a kind of throwaway code because once the external system (or component) will be completed we will test directly against it and therefore the whole mock pipeline with its components can be discarded.

What we need is a pre-defined pipeline whose stages are composed by custom pipeline components which reads behavior at run-time from external script files and acts on a message as soon as enters in BizTalk enabling us to test every possible input message in zero time.

Boo
Boo is an object oriented, statically typed programming language that seeks to make use of the Common Language Infrastructure's support for Unicode, internationalization and web applications, while using a Python-inspired syntax and a special focus on language and compiler extensibility.

Making an Internal DSL using boo is quite simple thanks to its DSL-friendly syntax and features, it also inherits from Python a REPL environment for quick testing and support for duckable types (which are simply what in .NET Framework 4 is called DynamicObject only realized in 2003...)

All these reasons made me choose Boo as the correct language to reach the goal i had in mind: a way to quickly implement prototypes to test EAI solution and its iterations with external environment.

Boo Mock Pipeline Component

Mocking BizTalk consists of three pipeline components, each component implements a different interface (IDisassemblerComponent,IAssemblerComponent, IComponent) therefore you can put them in each stage of your pipelines.

Component.png DisassemblerComponent.png AssemblerComponent.png

Parameters expected are the same for each type of PipelineComponent, what changes is the type of the variable expected to return from the script execution.
  • IsEnabled: Boolean indicating whether the pipeline component is active or not, this let user deactivate (or reactivate) pipeline component simply changing a parameter from biztalk administration console.
  • ScriptFile: Full path pointing to the boo script to execute when pipeline component is triggered (variable expansion is allowed so a path such as %EAI_ROOT%/Scripts/MyScript.boo is allowed.).
  • OutputVariable: the idea behind boo scripts is simple, in the script the user define the component behaviour declaring a new class and then assign an instance of the newly created class to a variable, the runtime extract this variable from the script environment and use it as pipeline component. Since the name of the output variable is defined in this parameter a single script may serve several pipeline components, each one getting a different instance using a different output variable name.

Boo Mock Pipeline

Even if you can use Pipeline Component in your pipelines Mocking Biztalk gives you a couple of pre-made pipelines (a send and a receive one) where each stage simply consists in a MockPipelineComponent.
In this way you may simply concentrate on your mock scripts, having both pipeline and components ready and installed.

Mock Receive Pipeline Mock Send Pipeline

Testing Orchestration
Let’s say an orchestration is triggered by messages with a particular promoted property

This is not an uncommon requirement, some adapter, such as the WCF SAP Adapter, promotes properties to indicate message types and other metadata about the message trasmitted.

In this situation using the FILE Adapter to simulate the external system is not a satisfiyng solution because FILE adapter can’t promote arbitrary properties, but using a boo script in out MockPipeline the problem became trivial such as writing the following script:

import Microsoft.BizTalk.Message.Interop from "Microsoft.BizTalk.Pipeline"
import Microsoft.BizTalk.Component.Interop from "Microsoft.BizTalk.Pipeline"


class myPromoter(IComponent):
	def Execute(ctx as IPipelineContext,msg as IBaseMessage) as IBaseMessage:
		msg.Context.Promote("MESTYP",”http://Microsoft.LobServices.Sap/2007/03/SapReceiveContextProperties/Idoc”,"MATMAS");
		return msg;

promoter = myPromoter()

In the screenshot below the pipeline configuration:

myPromoter.png

Testing Pipeline Component
Since Boo is a complete .NET Framework language (techically it’s a CLS Extender language) nothing prevent us from using MockPipeline to test out PipelineComponents without having to create a custom pipeline containing them.

Just for example sake, let’s say we’ve developed a Disassembler componente called MyDisassembler (declared in assembly MyDll.dll and in namespace myNamespace) and we want to test it without having to deploy it.

The following boo script does the trick

import myNamespace from "c:\MyProject\libs\myDll.dll"

disassembler = MyDisassembler()

Notice, in the screenshot below, how environment variables are allowed:

myDisassembler.png

Testing Maps
Usually MockPipelineComponent is not necessary to test maps: maps are simple XSLT applied to body part of messages and ignores other message features such as properties or other things but there’s a situation where having MockPipelineComponent is really handy.

Let’s say we have to invoke an (existing) external system throught a request-response port, but imagine that the external system has not implemented all operation we want to test (or there’s a bug in the existing implementation, whatever is the cause you obtain an inbound message different from what you expect to obtain in production environment).

Since we’re in a response branch of a two-way port we can’t simply use a fake FILE inbound port, we could implement a fake WebService receiving the message and answering with the expected response but again we’ll need to implement the webservice, to deploy it and to configure the port to invoke it.

A quicker solution consists in put a mock receive pipeline in the inbound part of the request response part, the script used by MockPipelineComponent simply will replace the answer message content (probably a “not implemented” error message) with the expected content.

The following boo script shows a naive way to do the replacement:
import Microsoft.BizTalk.Message.Interop from "Microsoft.BizTalk.Pipeline"
import Microsoft.BizTalk.Component.Interop from "Microsoft.BizTalk.Pipeline"

import System.IO
import System.Xml


class myReplacer(IComponent):
	def Execute(ctx as IPipelineContext,msg as IBaseMessage) as IBaseMessage:
		#NOTICE! This is a sample only... the usage of MemoryStream and XmlDocument objects in pipelines should be banned. Better is to use VirtualStream and/or XmlWriter.
		doc = XmlDocument()
		ms = MemoryStream()
		doc.LoadXml("<Pizzoccheri></Pizzoccheri>");
		doc.Save(ms)
		ms.Seek(0,SeekOrigin.Begin)
		msg.BodyPart.Data = ms;
		ctx.ResourceTracker.AddResource(ms);
		return msg;

replacer = myReplacer()

Use ONLY in test environment!
Better safe than sorry, this solution uses Interpreter API from Boo language and calls it directly from pipeline code, this approach is the quickest but has several drawbacks:

Each pipeline stage invoke Interactive Interpreter to compile on the fly the script passed as parameter, each compilation generates a temporary dll which is then loaded and executed from BizTalk Application Domain.

For every message received new dlls are compiled and loaded and cannot be unloaded (for Application Domain structure) without restarting the corresponding biztalk host instance.

This is not a big issue in a test environment where we can restart host instances without problems but in more controlled environment (such as production in not quality) this can be simply unfeasible.

Another drawback (connected to the one depicted above) is the fact that, compiling each script for each pipeline stage, the pipeline is definitely slower than one containing the same code pre compiled.

Maybe in future i’ll add some caching layer above the Interpreter API or will use the Boo Compiler API directly but considering the aim of this pipeline (usage in testing environment as Mock) this is unlikely at the moment.

Last edited May 7, 2010 at 11:31 PM by KidFashion, version 18