Want to show your appreciation?
Please a cup of tea.

Saturday, May 31, 2008

Raising Events in NMock 2.0

Neil Bourgeois posted an excellent article on this. I find myself often need EventHandler<TEventArgs> in addition to EventHandler, and also I would like to write Will(Hookup.Event(mockEvent)) because it reads more natually so easier to understand:
   1:MockEvent mockEvent = new MockEvent();
   2:Expect.Once.On(mockProvider).EventAdd("EffectiveUserChanged", Is.Anything)
   3:    .Will(Hookup.Event(mockEvent));
   4:mockEvent.Raise(mockProvider, EventArgs.Empty);
Here I added a static class Hookup and generic versions of Neil's classes.
   1:    /// <summary>
   2:    /// http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html
   3:    /// </summary>
   4:    /// <author>Neil Bourgeois</author>
   5:    /// <author>Kenneth Xu</author>
   6:    /// <seealso cref="MockEvent{TEventArgs}"/>
   7:    /// <seealso cref="Hookup"/>
   8:    public class MockEvent
   9:    {
  10:        private EventHandler _handler;
  11:
  12:        public void Initialize(EventHandler handler)
  13:        {
  14:            this._handler = handler;
  15:        }
  16:
  17:        public void Raise()
  18:        {
  19:            Raise(this, EventArgs.Empty);
  20:        }
  21:
  22:        public void Raise(object source, EventArgs e)
  23:        {
  24:            _handler.Invoke(source, e);
  25:        }
  26:
  27:    }
  28:
  29:    /// <summary>
  30:    /// http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html
  31:    /// </summary>
  32:    /// <author>Neil Bourgeois</author>
  33:    /// <author>Kenneth Xu</author>
  34:    /// <seealso cref="MockEvent"/>
  35:    /// <seealso cref="Hookup"/>
  36:    public class MockEvent<TEventArgs> where TEventArgs : EventArgs
  37:    {
  38:        private EventHandler<TEventArgs> _handler;
  39:
  40:        public void Initialize(EventHandler<TEventArgs> handler)
  41:        {
  42:            this._handler = handler;
  43:        }
  44:
  45:        public void Raise(object source, TEventArgs e)
  46:        {
  47:            _handler.Invoke(source, e);
  48:        }
  49:
  50:    }
  51:
  52:    /// <summary>
  53:    /// See BusinessContextTest for an example.
  54:    /// </summary>
  55:    /// <author>Kenneth Xu</author>
  56:    /// <seealso cref="MockEvent"/>
  57:    /// <seealso cref="MockEvent{TEventArgs}"/>
  58:    public static class Hookup
  59:    {
  60:        public static IAction Event(MockEvent mockEvent)
  61:        {
  62:            return new MockEventHookup(mockEvent);
  63:        }
  64:
  65:        public static IAction Event<TEventArgs>(MockEvent<TEventArgs> mockEvent)
  66:            where TEventArgs : EventArgs
  67:        {
  68:            return new MockEventHookup<TEventArgs>(mockEvent);
  69:        }
  70:
  71:        /// <summary>
  72:        /// http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html
  73:        /// </summary>
  74:        /// <author>Neil Bourgeois</author>
  75:        /// <seealso cref="MockEvent"/>
  76:        /// <seealso cref="MockEventHookup{TEventArgs}"/>
  77:        private class MockEventHookup : IAction
  78:        {
  79:            private readonly MockEvent mockEvent;
  80:
  81:            public MockEventHookup(MockEvent mockEvent)
  82:            {
  83:                this.mockEvent = mockEvent;
  84:            }
  85:
  86:            public void Invoke(Invocation invocation)
  87:            {
  88:                EventHandler handler = invocation.Parameters[0] as EventHandler;
  89:                if (handler == null)
  90:                    throw new Exception("Unknown event handler type: " + invocation.Parameters[0].GetType());
  91:                mockEvent.Initialize(handler);
  92:            }
  93:
  94:            public void DescribeTo(TextWriter writer)
  95:            {
  96:                // do nothing
  97:            }
  98:        }
  99:
 100:        /// <summary>
 101:        /// http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html
 102:        /// </summary>
 103:        /// <author>Neil Bourgeois</author>
 104:        /// <seealso cref="MockEvent{TEventArgs}"/>
 105:        /// <seealso cref="MockEventHookup"/>
 106:        private class MockEventHookup<TEventArgs> : IAction
 107:            where TEventArgs : EventArgs
 108:        {
 109:            private readonly MockEvent<TEventArgs> mockEvent;
 110:
 111:            public MockEventHookup(MockEvent<TEventArgs> mockEvent)
 112:            {
 113:                this.mockEvent = mockEvent;
 114:            }
 115:
 116:            public void Invoke(Invocation invocation)
 117:            {
 118:                EventHandler<TEventArgs> handler = invocation.Parameters[0] as EventHandler<TEventArgs>;
 119:                if (handler == null)
 120:                    throw new Exception("Unknown event handler type: " + invocation.Parameters[0].GetType());
 121:                mockEvent.Initialize(handler);
 122:            }
 123:
 124:            public void DescribeTo(TextWriter writer)
 125:            {
 126:                // do nothing
 127:            }
 128:        }
 129:    }
 130:

No comments:

Post a Comment