views:

666

answers:

2

I wanted to start with the use of Remoting under C# in a testdriven way, but I got stuck.

One thing I found on the topic is this article by Marc Clifton, but he seems to have the server running by starting it manually from the console.

I try to have the server started (i.e. register the serving class) in the test fixture. I probably also have the usage of the interface wrong, but that will come later.

I always get an Exception (sorry for the german message) that the channel is registered already. System.Runtime.Remoting.RemotingException : Der Channel tcp wurde bereits registriert.

After commenting out the ChannelServices.RegisterChannell() line in the test method, it occurs for the call Activator.GetObject().

I tried to put the StartServer() into a thread, but that did not help either. I found that creating a new AppDomain might be a possible way, but have not tried yet.

Can you tell me, if my approach is inherently wrong? How can I fix it?

using System;
using NUnit.Framework;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace Bla.Tests.Remote
{
    [TestFixture]
    public class VerySimpleProxyTest
    {
        int port = 8082;
        string proxyUri = "MyRemoteProxy";
        string host = "localhost";

        IChannel channel;

        [SetUp]
        public void SetUp()
        {
            StartServer();
        }

        [TearDown]
        public void TearDown()
        {
            StopServer();
        }

        [Test]
        public void UseRemoteService()
        {
            //IChannel clientChannel = new TcpClientChannel();
            //ChannelServices.RegisterChannel(clientChannel, false);
            string uri = String.Format("tcp://{0}:{1}/{2}", host, port, proxyUri);
            IMyTestService remoteService = (IMyTestService)Activator.GetObject(typeof(IMyTestService), uri);

            Assert.IsTrue(remoteService.Ping());
            //ChannelServices.UnregisterChannel(clientChannel);
        }

        private void StartServer()
        {
            channel = new TcpServerChannel(port);
            ChannelServices.RegisterChannel(channel, false);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyTestService), proxyUri, WellKnownObjectMode.Singleton);
        }

        private void StopServer()
        {
            ChannelServices.UnregisterChannel(channel);
        }
    }

    public interface IMyTestService
    {
        bool Ping();
    }

    public class MyTestService : MarshalByRefObject, IMyTestService
    {
        public bool Ping()
        {
            return true;
        }
    }
}
A: 

I found a nice way to do exactly what I wanted to do, just using WCF instead of Remoting.

I ported the source code given in the article by Yair Cohen to NUnit within less than 5 minutes and it works out of the box.

GrGr
A: 

I don't really have a solution to your problem but my advice would be, not to write unit-tests in this manner. See this post. What code do you really want to test here. I'm pretty sure Microsoft has done a good deal of testing the Remoting feature that ships with .net. The class that implements your Service interface can be unit tested in proces by just newing up the implementation. The code that registers your service interface would have been testable if the .net framework didn't use statics for the registration bit, but alas. You could try to pass an IChannel mock to ChannelServices.RegisterChannel and verify your registration code in some manner this way but in my opionion this would be a waste of time.

I would just like to state that testing should be a means to an end but not a goal in itself.

Bas Bossink
Test driven doesn't just mean unit tests you know, it can include integration tests and end to end testing of transactions. It might may TDD people cry but in addition to unit tests I tend to do WCF integration tests within a unit test harness, spinning up the WCF host, firing off a message and testing the response. That certainly isn't a waste of time.
blowdart