• No results found

After a map is developed, validated, tested, and possibly debugged, you should enable unit testing of the map. As a matter of fact, many great people insist you should write your unit tests before even starting developing anything. This is called test-driven development (TDD). In either case, BizTalk ships with the option to do unit testing on your maps, which you should leverage, and this section describes this functionality.

The first thing to do is to enable unit testing on the project that contains a map you want to unit test. To do so, follow these steps:

1. Go to Solution Explorer.

2. Right-click the project that contains the map that is to be unit tested, and choose Properties.

3. Go to the Deployment pane and enable the Enable Unit Testing property, as shown in Figure 3.44.

FIGURE 3.43 Debugging a map.

ptg7041380

3

FIGURE 3.44 Enabling unit testing on project.

After enabling unit testing on the project, all maps in the project that are compiled will be inheriting from the TestableMapBaseclass in the Microsoft.BizTalk.TestTools.Mapper namespace instead of the normal TransformBaseclass in the Microsoft.XLANGs.BaseTypes namespace. The TestableMapBaseclass actually inherits from TransformBase, so nothing is lost. What is gained, however, are some methods and properties that can be leveraged for unit testing.

Next, you should add a test project to your solution. This is done by using the menu in Visual Studio 2010, where you can click Test, New Test to open the screen shown in Figure 3.45. In this screen, you can choose to either add the new test to an existing test project, if one is present in the solution, or create a new Visual C# test project. In addi-tion, you can choose between four different tests:

. Ordered Test: This gives you a way of orchestrating your tests, deciding what order they should be performed in.

. Unit Test: This option gives you a class to write your tests in, but some manual work needs to be done like referencing the right assemblies and so on.

. Basic Unit Test: This option provides an even smaller and simpler version of a unit test class than the unit test. More to implement yourself.

. Unit Test Wizard: This helps you through some of the choices you must make, like what maps to test, and then generates the test class for you.

The other five options for adding a new test are not relevant for a BizTalk project.

For your first test project, name your file, choose Unit Test, and click OK. If you already have a test project, you can decide to add the file to an existing project by selecting it in the drop-down.

ptg7041380 The test project is created for you, and it includes a pretty empty class for your tests. The

class contains some definitions, methods, a constructor, and one method that is really the one thing to focus on, because this is the one you need to implement.

FIGURE 3.45 Adding a new test to your test project.

So, what you need to do in this method is to implement the unit test of the maps you want to test in this test class. Remember that you can have as many test classes and test methods in each test project as you want.

To test a map, you need to reference three different assemblies from your test project:

. The assembly that contains the map: This assembly must have the Enable Unit Testing property set to True.

. The Microsoft.BizTalk.TestTools assembly: This is found in the .NET pane of the Add Reference screen.

. The Microsoft XLANG/s Base Types assembly: This is also found in the .NET pane of the Add Reference screen.

In the project, the XML instances that are to be used for the unit test can also be added. If you do this, consider marking their Build Action property to None, so they are not

compiled needlessly into the assembly. The instances are not required to be included in the project, but it gives you a nice way of having everything needed for the test grouped together.

After adding the project references, you need to implement the test method. Locate the method in the class file called TestMethod1, and change it to something like the code shown in Listing 3.20.

ptg7041380

3

LISTING 3.20 Sample Test Method for Testing a Map [TestMethod]

public void TestMapC1702OrderToFineFoodsOrder() {

string INPUT = testContextInstance.TestDir + @”\..\Order.xml”;

string OUTPUT = testContextInstance.TestDir + @”\..\MappedOrder.xml”;

TestableMapBase map = new Order_to_InternalOrder();

// Read in OUTPUT and check relevant values.

// Compare file with expected output.

}

The two strings INPUTandOUTPUTare declared to contain the path to the input instance for the map and the path to the output file to write the output to. The functionality required basically instantiates the map as a TestableMapBaseclass, which contains the needed properties and methods for unit testing. Then the properties ValidateInputand ValidateOutputare set to true. These properties mean the same as the properties you can set on the .BTM file and will determine whether the TestMapmethod should validate the input and output against the respective schemas before and after the map is executed. Any failures in this validation results in the test failing. Both values are falseby default.

For the code to compile, the usingstatements shown in Listing 3.21 are needed. The namespaces are as follows:

. Microsoft.VisualStudio.TestTools.UnitTesting: This is the namespace needed to use the TestClassandTestMethodattributes.

. FineFoods.Customers.FamilyRestaurant: This is the namespace the map is located in, providing you access to theOrder_to_InternalOrderclass that is the compiled map.

. Microsoft.BizTalk.TestTools.Mapper: This namespace contains the TestableMapBaseclass needed to call methods on the map object.

. Microsoft.BizTalk.TestTools.Schema: This namespace contains the two enumera-tions used for specifying the type of input and the type of the output for the TestMapmethod.

. System.IO: This is used to be able to access the Fileclass that is used to check whether the output file exists in the assertion that is in the testmethod.

ptg7041380 LISTING 3.21 using Statements Necessary for Code in Listing 3.20

using Microsoft.VisualStudio.TestTools.UnitTesting;

using FineFoods.Customers.C1702;

using Microsoft.BizTalk.TestTools.Mapper;

using System.IO;

using Microsoft.BizTalk.TestTools.Schema;

The code in Listing 3.20 shows just one assertion, which basically asserts that the output file is created. You might need other assertions, such as comparing the output to an instance of the expected output or reading in the output file and validating some of the actual values created.

You should have as many instances as needed to make sure your map can handle all possi-ble instances correctly. This means you should have plenty of input instances and possibly plenty of samples of the output.

You can find Microsoft’s description of the unit test features at http://msdn.microsoft.com/en-us/library/dd224279(BTS.70).aspx.

Summary

A map is a transformation from one XML format into another. It is important that maps generate valid output, because otherwise you can send invalid XML to customers, trading partners, internal systems, and others. Because the input to a map can be quite compli-cated XML with lots of optional fields and even fields that are not optional yet are still marked as such in the schema, developing a single map that deals with the possible inputs to the map can present a big challenge. Take care and study the input and output schemas and determine how to handle all special cases.

Maps are developed in the Mapper, which in turn is converted into XSLT, and you can even provide your own XSLT instead of that which is generated. BizTalk Server 2010 provides an all-new Mapper that helps developers get a good overview of the map to keep track of it and that helps developers change an existing map. The Mapper provides a nice and intu-itive user interface for building your transformations. It provides functionality to both copy values directly from the source to the destination and also functoids that provide function-ality that is performed on the source before it is mapped to the destination.

BizTalk ships with a lot of functoids that you can use as building blocks for the most common mapping challenges. If you run into either functionality that the built-in func-toids cannot handle or a combination of funcfunc-toids you use a lot and want to group together, you can build your own functoids. Custom functoids have access to the entire .NET framework for referenced functoids and a subset of the .NET framework for inline functoids, providing you with the power of expression you need to do almost anything.

ptg7041380

I

n a BizTalk solution, you can get pretty far with schemas, maps, pipelines, and artifacts like receive ports, send ports, and so on. This is called a messaging-only solution.

Sometimes, however, you either need to use a more complex process to be able to do things to incoming messages that you cannot do with a messaging-only solu-tion, or sometimes you actually have a business-defined business process that you want to digitalize. This is what orchestrations can do for you.

A business process can be the process that takes place when a sales order arrives, such as receive order, send order confir-mation, send sales order to enterprise resource planning (ERP) system, receive purchase orders from ERP system, send purchase orders to suppliers, receive order confirmations from supplier, and so on. It can also be something like a service aggregator orchestration, meaning that BizTalk can expose a service called CreateNewEmployee, which is called by some internal system, and BizTalk then in turn calls all the needed systems that need updating when a new employee is hired, such as creating the employee in the different internal systems, ordering some flowers for her, ordering a new laptop or desk, and stuff like that.

What is nice about letting BizTalk handle these business processes is that BizTalk first provides clever persistence out-of-the-box, meaning that even though the server running BizTalk crashes during the execution of a business process, nothing is lost, and when BizTalk is up and running again, it will just restarts the business process at the correct point.

The only things that might be lost are the things that BizTalk has no control over. (For example, if you had called a .NET helper class that did something.) Using atomic

ptg7041380 transactions and .NET classes that can enlist in transactions can help you here. This is

explained later. Second, BizTalk provides transactions inside the business process, enabling you to run transactions against the systems you talk to if the systems support this, but also provides mechanics to help you undo what has been done earlier in a business process if some business exception arises at some point later in the process.

Orchestrations do not have to be all-covering, but instead you can develop many small orchestrations and let one orchestration call the smaller ones. This provides you with the option to let multiple developers each work on their part of the business process at the same time, and it also modularizes the business process, allowing you to create reusable small orchestrations that can be used from multiple orchestrations.