Implementing a Custom BizTalk Adapter as a Custom WCF Channel Part 3 – Testing

When testing your WCF Channel, it can be simpler and quicker to do it directly from Visual Studio without needing to add the assembly to the GAC, restart BizTalk and attach to BTSNTSvc.exe each time you changed the code.

Testing the send side is simple. Create a new test project and add the following interface and class:

[ServiceContract]
interface IBizTalk
{
    [OperationContract(Action="*", ReplyAction="*")]
    Message Request(Message message);
}

class TestClient : ClientBase<IBizTalk>, IBizTalk
{
    public Message Request(Message message)
    {
        return base.Channel.Request(message);
    }
}

Then, write a test method:

[TestMethod]
public void TestSend()
{
    byte[] buffer = UTF8Encoding.UTF8.GetBytes("Hello, world!");
    Message msg = Message.CreateMessage(MessageVersion.Default, "Dummy", buffer);
    TestClient testClient = new TestClient();
    Console.Out.WriteLine(testClient.Request(msg).ToString());
    testClient.Close();
}

You also need an application configuration file (app.config):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint address="net.file://localhost/test" binding="customBinding" bindingConfiguration="customBinding" contract="WCFFileTransport.IBizTalk" name="WCFFileTransport" />
    </client>
    <bindings>
      <customBinding>
        <binding name="customBinding">
          <WCFFileAdapter fileName="E:BizTalkTestMessagesWCFFileAdapterOut%datetime%.txt" useXmlWrapper="true" />
        </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>
</configuration>

After running the test method, you should have a text file in the out folder.

On the receive side, you can create a console application to host the service like this:

[ServiceContract]
public interface IBizTalk
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void Receive(Message message);
}

class TestService : IBizTalk
{
    public void Receive(Message message)
    {
        Debug.WriteLine(message.ToString(), "Test");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
        ServiceHost service = new ServiceHost(typeof(TestService));
        service.Open();
        Console.WriteLine("Press <ENTER> to terminate the service and exit.");
        Console.ReadLine();
        service.Close();
    }
}

You need the following application configuration (app.config):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="TestService.TestService">
        <endpoint address="net.file://localhost/test.svc" binding="customBinding"
          bindingConfiguration="customBinding" name="WCFFileTransport"
          contract="TestService.IBizTalk" />
      </service>
    </services>
    <bindings>
      <customBinding>
        <binding name="customBinding">
          <WCFFileAdapter fileName="E:BizTalkTestMessagesWCFFileAdapterIn*.xml" useXmlWrapper="true" />
        </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Drop a file matching the file mask in the in folder, and you should have a message printed in the console.

If you like more control, you could use the following code instead:

private bool complete = false;

[TestMethod]
public void TestReceive()
{
    FileBindingElement bindingElement = new FileBindingElement();
    bindingElement.FileName = @"E:BizTalkTestMessagesWCFFileAdapterIn*.xml";
    bindingElement.UseXmlWrapper = true;
    BindingParameterCollection parms = new BindingParameterCollection();
    CustomBinding binding = new CustomBinding(new BindingElement[] { bindingElement });
    BindingContext context = new BindingContext(binding, parms);
    context.ListenUriBaseAddress = new Uri("net.file://localhost/test.svc");
    IChannelListener<IInputChannel> listener = bindingElement.BuildChannelListener<IInputChannel>(context);
    listener.Open();
    IInputChannel channel = listener.AcceptChannel();
    channel.Open();
    Message msg;
    IAsyncResult result = channel.BeginTryReceive(TimeSpan.FromSeconds(60.0), new AsyncCallback(Callback), new object());
    while (!complete)
        System.Threading.Thread.Sleep(1000);
    channel.EndTryReceive(result, out msg);
    Console.WriteLine(msg.ToString());
    Assert.IsNotNull(msg);
}

public void Callback(object state)
{
    complete = true;
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s