Integration testing with mocks

BizTalk applications often uses external services as a part of the process. When developing and testing such applications, those services might not be available. They might be under development, or just not accessible from the test environment. To be able to test the BizTalk application, we need to simulate (mock) the external services.

For this example, we use a modified version of the application described in the Multi-application solutions chapter. Instead of calling another BizTalk orchestration, the service will be external to BizTalk.

Open the “Contoso.Math” application in the BizTalk admin console, and unenlist the “GenerateFibonacci” orchestration. Then, start the “GenerateFibonacciRequestSendPort” and enable the “GenerateFibonacciResponseReceiveLocation” receive location. Requests to the service will now be sent to a file share, and responses read form another. The external “GenerateFibonacci” service will listen to the request folder, and send messages back to the response folder.

Mock1.PNG

Since we had set up the calling orchestration to communicate via the BizTalk message box in the proper way, we did not have change anything there. The calling orchestration (SqaureFibonacciSequence) does not know that the “GenerateFibonacci” service is no longer provided by an orchestration, but handled by an external service.

The application set-up now looks like this.

IntegrationTest2.png

To test the BizTalk application, our integration test has to act as both the “Client” and the “GenerateFibonacci” service.

There are two integration tests located in the samples code. “FibonacciSquared.cs” and “FibonacciSquaredExternal.cs” The first test is for the scenario where the service is implemented as an orchestration. The test is implemented the same way as described in the Integration test chapter.

In the “FibonacciSquaredExternal” test, a method has been added that act as the “GenerateFibonacci” service. This method is started as a separate thread when the test starts, and polls the "Requests" folder for messages. When a message arrives, the method processes it, and returns the response.

    private void ProcessRequests()
    {
      XDocument request;
      XDocument response;
      XNamespace ns1;
      XNamespace ns2;
      XElement seq;
      string uow;
      string length;
      long[] f;

      ns1 = "http://contoso.com/biztalkdemo/generatefibonaccirequest/v1";
      ns2 = "http://contoso.com/biztalkdemo/generatefibonacciresponse/v1";

      while (this.running)
      {
        foreach (string file in Directory.EnumerateFiles(GenerateFibonacciRequestFolder, "*.xml"))
        {
          request = XDocument.Load(file);
          uow = request.Descendants(ns1 + "UnitOfWorkID").First().Value;
          length = request.Descendants(ns1 + "Length").First().Value;

          f = this.GenerateFibonacciSequence(int.Parse(length));

          seq = new XElement(ns2 + "FibonacciSequence");
          for (int i = 0; i < f.Length; i++)
          {
            seq.Add(new XElement(ns2 + "V", f[i]));
          }
          
          response = new XDocument(
                     new XElement(ns2 + "GenerateFibonacciResponse",
                      new XElement(ns2 + "UnitOfWorkID", uow),
                      seq));

          response.Save(Path.Combine(GenerateFibonacciResponseFolder, uow + ".xml"));
          File.Delete(file);
        }

        Thread.Sleep(1000);
      }
    }

In more advanced scenarios, code should be added to this method to verify that the request message from BizTalk is correct. If your BizTalk application calls more than one external service, just add methods to mock those services and run them as separate threads.

Last edited Mar 17, 2014 at 9:30 AM by hallis, version 11