Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Moq 'intercepts' events by detecting calls to an event's internal methods. These methods are named <code>add_</code> + the event name and are 'special' in that they are non-standard C# methods. Events are somewhat like properties (<code>get</code>/<code>set</code>) and can be defined as follows:</p> <pre><code>event EventHandler MyEvent { add { /* add event code */ }; remove { /* remove event code */ }; } </code></pre> <p>If the above event was defined on an interface to be Moq'd, the following code would be used to raise that event:</p> <pre><code>var mock = new Mock&lt;IInterfaceWithEvent&gt;; mock.Raise(e =&gt; e.MyEvent += null); </code></pre> <p>As it is not possible in C# to reference events directly, Moq intercepts all method calls on the Mock and tests to see if the call was to add an event handler (in the above case, a null handler is added). If so, a reference can be indirectly obtained as the 'target' of the method.</p> <p>An event handler method is detected by Moq using reflection as a method beginning with the name <code>add_</code> and with the <code>IsSpecialName</code> flag set. This extra check is to filter out method calls unrelated to events but with a name starting <code>add_</code>.</p> <p>In the example, the intercepted method would be called <code>add_MyEvent</code> and would have the <code>IsSpecialName</code> flag set.</p> <p>However, it seems that this is not entirely true for interfaces defined in interops, as although the event handler method's name starts with <code>add_</code>, it does <em>not</em> have the <code>IsSpecialName</code> flag set. This may be because the events are being marshalled via lower-level code to (COM) functions, rather than being true 'special' C# events.</p> <p>This can be shown (following your example) with the following NUnit test:</p> <pre><code>MethodInfo interopMethod = typeof(ApplicationEvents4_Event).GetMethod("add_WindowActivate"); MethodInfo localMethod = typeof(LocalInterface_Event).GetMethod("add_WindowActivate"); Assert.IsTrue(interopMethod.IsSpecialName); Assert.IsTrue(localMethod.IsSpecialName); </code></pre> <p>Furthermore, an interface cannot be created which inherits the from interop interface to workaround the problem, as it will also inherit the marshalled <code>add</code>/<code>remove</code> methods.</p> <p>This issue was reported on the Moq issue tracker here: <a href="http://code.google.com/p/moq/issues/detail?id=226" rel="nofollow noreferrer">http://code.google.com/p/moq/issues/detail?id=226</a></p> <p><strong>Update:</strong></p> <p><strike>Until this is addressed by the Moq developers, the only workaround may be to use reflection to modify the interface which seems to defeat the purpose of using Moq. Unfortunately it may be better just to 'roll your own' Moq for this case.</strike></p> <p>This issue has been fixed in Moq 4.0 (Released Aug 2011).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload