[TFUI] Mocking .Net Controls/Forms

Tim Haughton <[email protected]> Mon, 7 Nov 2005 09:11:10 +0000
Newsgroups gmane.comp.programming.test-first-user-interfaces
Message-ID <[email protected]>
Hi, I recently added a new type of dynamic mock to NMock. The mock was
originally designed to mock out some remoted classes, but works with
any MarshalByRefObject, so it works with any .Net Control/Form. Also,
unlike the existing dynamic mock, this new mock will be able to mock
*any* methods, not just virtual ones.

In case the NMock team don't [want / get around] to adding it to a
release, I thought I'd post them here for reference. Comments and
flames welcome.

Cheers,

Tim Haughton


//*********MarshalByRefMock.cs*********************
using System;
using NMock;

namespace NMock.Remoting
{
	public class MarshalByRefMock : Mock
	{
		private Proxy proxy;

		public MarshalByRefMock( Type type )
			: this( type, "Mock" + type.Name )
		{
		}

		public MarshalByRefMock( Type type, string name )
			: base( name )
		{
			proxy = new Proxy( type, new MockInvokeDelegate(Invoke) );
		}

		public override object MockInstance
		{
			get
			{
				return proxy.GetTransparentProxy();
			}
			set
			{
				throw new NotSupportedException( "Setting the MockInstance
programmatically is not supported for this type." );
			}
		}

	}
}

//*********End of file****************


//*************Proxy.cs****************

using System;
using System.Reflection;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Channels;

namespace NMock.Remoting
{
	public delegate object MockInvokeDelegate(string methodName, params
object[] args);

	public class Proxy : RealProxy
	{
		private MockInvokeDelegate invokeMethod;

		public Proxy( Type type, MockInvokeDelegate invokeMethod )
			: base( type )
		{
			this.invokeMethod = invokeMethod;
		}

		public override IMessage Invoke(IMessage msg)
		{
			string methodName	= msg.Properties["__MethodName"] as string;
			object[] args		= msg.Properties["__Args"] as object[];			
				
			object response = invokeMethod( methodName, args );

			MethodBase mb = RemotingServices.GetMethodBaseFromMethodMessage(
(IMethodMessage)msg );
			ParameterInfo[] parameters = mb.GetParameters();

			int outCount = 0;
			object[] outs = new object[args.Length];

			foreach( ParameterInfo p in parameters )
			{
				if ( p.IsRetval || p.IsOut )
					outCount++;
			}

			int moveBy = args.Length - outCount;

			for ( int i = outCount - 1; i >= 0; i-- )
			{
				outs[i + moveBy] = args[i];
			}

			Header h1 = new Header( "__Return", response );
			Header h2 = new Header( "__OutArgs", outs );

			MethodResponse mr = new MethodResponse( new Header[]{h1,h2},
(IMethodCallMessage)msg );
			

			return mr;
		}
	}
}

//**********End of file*****************




------------------------ Yahoo! Groups Sponsor --------------------~--> 
Get Bzzzy! (real tools to help you find a job). Welcome to the Sweet Life.
http://us.click.yahoo.com/A77XvD/vlQLAA/TtwFAA/nhFolB/TM
--------------------------------------------------------------------~-> 

To unsubscribe, email:
TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org
 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/TestFirstUserInterfaces/

<*> To unsubscribe from this group, send an email to:
    TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/