fredag 9. januar 2015

Testing a real world BizTalk integration with TransMock - Part 1

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:
  1. An SO is registered in the ERP and a reservation message for the products is sent over a MSMQ queue to BizTalk
  2. The reservation is then sent further to the warehouse system over a web service call.
  3. 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
  4. 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
  5. 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.
  6. 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.
  7. 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.
  8. 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.

Modifying the bindings file

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:

<Import Project="[Path to the installation folder of TransMock]\Ext\TransMock.targets" />

By default TransMock is installed under the folder "C:\Program files (x86)\TransMock" on a 64-bit machine and the Import tag would look like this:

<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

Ingen kommentarer:

Legg inn en kommentar