TransMock is a neat
little framework that allows you to easily test the functionality of a BizTalk
Server integration on a developer box or a build server without the need of
complex set ups of system test instances or respective stubs and mock-ups.
In this series of blog posts I
will demonstrate how easy it is to test an existing integration with this
framework.
Ovreview
The integration used as an example is based on a real life implementation of a SO and shipment procurement process. The whole process involves multiple interfaces implemented as separate discrete integrations, so for the sake of simplicity these are all merged together in a single application.
The process flow is
as follows:
- An SO is registered in the ERP and a reservation message for the products is sent over a MSMQ queue to BizTalk
- The reservation is then sent further to the warehouse system over a web service call.
- The warehouse system supplies an synchronous response of the reservation to BizTalk over another web service call, which is then sent back to the ERP over another MSMQ queue
- The shipment for the SO is prepared in the ERP and when it is finished a shipment request is sent over FTP to an external logistics provider. EDI message is used for this purpose
- The logistics provider sends a confirmation that they can handle the shipment with another EDI message over FTP. This message is transformed to the corresponding ERP format and sent back to the ERP over a MSMQ.
- When the time for shipping the goods has come a packing request is sent from the ERP over an MSMQ and BizTalk sends it further to the warehouse system over another web service call.
- Once the goods are packed and prepared to be shipped a ready to ship message is sent back from the warehouse system over a web service call to BizTalk and it sends it further to the ERP over MSMQ.
- Once the goods are picked and shipped by the shipping provider an ASN - advanced shipment notice message is sent over FTP from the shipping provider to the ERP and the customers which effectively finlizes the process.
As you can see there
are a number of different message formats and a number of different transport
protocols used in this integration solution. This is the norm for a typical BizTalk server based solution.
So, before carrying
out with the instructions on how to test this integration with the help of
TransMock few clarifications should be made:
- First of all, the integration implementation uses BTDF for managing the packaging and deployment to the different environments.
- Secondly, the message formats and details are much more simplified for the sake of clarity. Remember that the purpose of the post is not to go in detail on how to define a schema for a message to a warehousing system or a logistics provider, but instead to emphasize on how to test an integration without the need of implementing some complex mockups of those systems, or even installing and configuring a specific test instance of a specific system for that purpose.
- And lastly, it is assumed that you are familiar with BizUnit based tests and that you have installed both BizUnit and the TransMock framework on your dev box.
Alright, time for
fun.
The first thing that you need
to do is to identify the receive locations and send ports that are
involved in communicating with the system interfaces in question. In our
bindings file this is what we find
System name
|
Receive location name
|
Send port name
|
Purpose
|
Dynamix AX
|
ERP_SOCreatedIn_MSMQ
|
SO created
|
|
Dynamix AX
|
ERP_PackageNotificationIn_MSMQ
|
Package and ship
|
|
Dynamics AX
|
ERP_SOReservationOut_MSMQ
|
Reservation
response
|
|
Dynamics AX
|
ERP_ReadyToShipOut_MSMQ
|
Ready to ship
response,
|
|
Dynamics AX
|
ERP_ShipmentConfirmOut_MSMQ
|
Tender response
|
|
Dynamics AX
|
ERP_ASNOut_MSMQ
|
Shipment ASN
|
|
Warehouse
|
WMS_InventoryManagementOut_WCF
|
Reservation,
Package and ship
|
|
Warehouse
|
WMS_InventoryManagementIn_WCF
|
Ready to ship response
|
|
Shipping Partner
|
SHP_ShipmentRequestOut_EDI_SFTP
|
Transportation
tender request |
|
Shipping Partner
|
SHP_ShipmentUpdateOut_EDI_SFTP
|
Shipment update
request
|
|
Shipping Partner
|
SHP_TendertResponseIn_EDI_SFTP
|
Shipment response
|
|
Shipping Partner
|
SHP_ShipmentUpdateIn_EDI_SFTP
|
Shipment update
response
|
|
Shipping Partner
|
SHP_ASN_FTP
|
Shipment ASN
|
In
total we have 6 receive locations and 7 send ports. Please note that both the
receive locations and send ports are being used to respectively send and
receive different message types (* might be not correct according to the
standard usage of these artifacts). This makes the testing even more
challenging.
Once we have identified these
the next step is to mark them as eligible for mocking. This is done by
adding the Mock tag in a comment right under the respective
ReceiveLocation and SendPort elements in the bindings file. In the snippet
below is shown an example of that:
... <SendPort name="WMS_InventoryManagementOut_WCF"> <!-- <Mock />--> ... </SendPort > ... <ReceiveLocation name="ERP_SOReservationOut_MSMQ"> <!-- <Mock /> --> ... </ReceiveLocation > ...
This
is the most simple way of preparing the bindings file for mocking by TransMock.
By applying the Mock tag the Mockifier replaces the actual adapter configuration in
each and every receive location and send port that is marked for mocking with a
predefined configuration of the mock adapter. In addition it replaces the
address property with a mock URL. By default the mock URL is containing the
name of the corresponding receive location or send port by following the
pattern mock://localhost/[Receive location name | Send port name] . This
might sometimes be a bit difficult to read and not that nice looking. I would
therefore like to demonstrate one feature of the framework which allows to have
customized mock URLs which are easier to understand. For this purpose I would
simply set value for the attribute EndpointName in each appearance of the Mock
tag, as shown in the snippet below:
… <SendPort Name="WMS_InventoryManagementOut_WCF" …. > <!-- <Mock EndpointName="WMS_InventoryManagementOut" /> --> … </SendPort> … <ReceiveLocation Name="ERP_SOProcurementOut_MSMQ"> <!-- <Mock EndpointName="ERP_SOProcurementOut" /> --> … </ReceiveLocation> …
The
resulting URLs would then be as follows:
mock://localhost/WMS_InventoryManagementOut
for the WMS_InventoryManagementOut_WCF send port, and
mock://localhost/ERP_SOProcurementOut
for the ERP_SOProcurementOut_MSMQ receive location
As
you can see I have simply removed the name of the original transport in each of
the EndpointName values which makes the URLs much more understandable and
minimizing the confusion it might create when the original transport name is
there.
Please
note that this is not required to have the TransMock working correctly. It is a
technique for modifying the default mock URLs which might be handy in many
situations.
With
this we are done with preparing the bindings file for being used by the
TransMock framework.
Modifying the .btdfproj file
It is now time to modify the btdfproj file so that the Mockifier of the TransMock framework is invoked properly. There are couple of things that need to be done to make this happen. First of all there should be added a reference to a targets file that contains the TransMock build targets. This is done by adding the following code at the very end of the .btdfproj just before the closing Project tag:
Modifying the .btdfproj file
It is now time to modify the btdfproj file so that the Mockifier of the TransMock framework is invoked properly. There are couple of things that need to be done to make this happen. First of all there should be added a reference to a targets file that contains the TransMock build targets. This is done by adding the following code at the very end of the .btdfproj just before the closing Project tag:
<Import Project="[Path to the installation folder of TransMock]\Ext\TransMock.targets" />
<Import Project="C:\Program files (x86)\TransMock\Ext\TransMock.targets" />
Update: Since TransMock v 1.3 the only distribution channel for the framework is NuGet. Hence the Import tag will look as follows:
<Import Project="..\packages\TransMock.Framework.[version in format X.Y.Z]\BTDF\TransMock.targets" />
There are few TransMock specific project properties that should be set. These are:
- BTSVersion - optional, should be set to 2010 if BizTalk 2010 solution is being tested. No need to be set when 2013/R2 solution is being tested.
- TransMockAddressClassDir - optional, this should be se to the path where the test project containing the TransMock tests resides. Relative paths is the preferred format. If not set the helper class generated by the Mockifier would be saved in the same directory where the btdfproj file resides.
- TransMockHomeDir - optional. This property should only be set in the case when TransMock is installed in a location different than the default one. It should contain this custom path then.
In
our case the BizTalk version is 2013 R2, the test project is called
IntegrationTests and resides in a subfolder with the same name under the
solution root and TransMock is installed at the default location. Hence only
the value of the TransMockAddressClassDir
property will be set:
<TransMockAddressClassDir>..\IntegrationTests</TransMockAddressClassDir>
With
this the btdfproj file is prepared for running the Mockifier as part of the
BTDF deploy process.
At
this point you should build and deploy the solution which will result in
importing the bindings with all the receive locations and send ports having the
mock adapter as their transport and their addresses having mock URLs. In
addition a file called SOProcurementMockAddresses.cs has been generated in the
IntegrationTests folder.
Continue to Part 2