The first step in testing your application should be to test each component individually, outside the MTS environment—the same kind of unit testing that you do for any other kind of code. The easiest way to test your components is to write a simple test harness that exercises all the functionality exposed by the COM classes. Scripting languages and rapid application development (RAD) tools such as Microsoft VBScript and Microsoft Visual Basic are great ways to build simple test harnesses. You might also want to write a multithreaded test harness to be sure that you don't have any concurrency problems in your component. The goal is to verify that the application logic of your component works correctly, before you put the component into the distributed application environment. Many programming tools provide only limited support for debugging components running within MTS, so the more bugs you can eliminate up front, the better.
Microsoft Visual J++ 1.1 and Microsoft Visual Basic 5.0 are among the tools with poor debugging support for components running within MTS. The Visual J++ 1.1 debugger cannot debug Java classes that have been converted to COM classes. The Visual Basic 5.0 debugger cannot debug compiled components such as those you would install in MTS. Visual Basic 6.0 provides better debugging support for MTS components in some scenarios.
One potential problem with testing components outside the MTS environment is that your component code typically uses the object context. When your component runs outside the MTS environment, the object context is not available. There are several ways to address this problem.
If the release version of your component might run both within and outside the MTS environment, you should check whether the object context exists at run time before you make any method calls. If your released component always runs within MTS, you probably don't want to add the overhead of checking for the object context before every method call. In this case, conditional compilation is a useful approach if your programming language supports it. This technique is straightforward for calls to SetComplete or SetAbort —you can just leave the call out, as shown here in C++:
#ifndef NO_MTS_CONTEXT m_spObjectContext->SetComplete(); #endif
However, you can't leave out calls to create subordinate objects. In this case, you need to call a regular object creation function instead of the ObjectContext CreateInstance method, as in the following example:
IMyInterface* ptr; #ifdef NO_MTS_CONTEXT hr = CoCreateInstance(__uuidof(MyClass), NULL, CLSCTX_SERVER, reinterpret_cast<void**>(static_cast<IMyInterface**>&ptr)) #else hr = m_spObjectContext->CreateInstance(__uuidof(MyClass), reinterpret_cast<void**>(static_cast<IMyInterface**>&ptr)) #endif
This code is ugly enough to deserve encapsulation in a macro or inline function! The disadvantage of this approach is that you need to build a special version of your component to run outside MTS. There is a slight risk that your application logic might be correct in this version and incorrect in the version built for MTS, but it is the best approach available for testing components written in C++ or Visual Basic 6 outside MTS.
Another approach can be used with components written using Visual Basic 5.0. MTS provides a debug version of the ObjectContext, whose methods provide the behavior described in the following table.
|CreateInstance||Calls COM CoCreateInstance (no context flows, no transactions, and so on)|
This debug version of the ObjectContext can be enabled by adding the following registry key in the HKEY_LOCAL_MACHINE hive: Software\Microsoft\Transaction Server\Debug\RunWithoutContext.
This registry key is recognized only by Visual Basic 5.0; Visual Basic 6.0 will ignore the key. In Visual Basic 5.0, the GetObjectContext function will return the debug ObjectContext. Before testing your components within MTS, you need to remember to disable the debug ObjectContext by removing this key. The major advantage of this approach is that you don't need to build a special version of your component—it's the easiest way to test components written in Visual Basic 5.0 outside MTS.
Be careful when you are testing components that perform multiple database updates outside MTS. Since you do not have automatic transactions outside MTS, it is possible to end up with partial updates and inconsistent data. Use test databases, along with scripts to clean out and repopulate the databases with good data, during development testing and debugging.