Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement verification of event handler attaches and detaches (something like mock.Verify(m => m.Event += callback)) #49

Closed
joebeernink opened this issue May 27, 2013 · 16 comments

Comments

@joebeernink
Copy link

I'm working on some code where an object subscribes a private method to an event of a passed-in class. In my unit tests I'd like to see how many handlers have been attached to the event. There should only be one, but it is possible that there could be more than one (I know this because I had a bug that let the += execute twice). I wanted to write a unit test to report when this happens.

I saw this question on the old MOQ site, but there haven't been any updates in a while. Is it still an open request? https://code.google.com/p/moq/issues/detail?id=100

Thanks

@benbishop
Copy link

I too would love to have this feature. I'm currently doing a lot of Xamarin mobile work. With views, you need to be able to add and remove event listeners in a very strict fashion to ensure you don't create memory leaks going from screen to screen.

Currently in my unit tests I can test if the behavior still exists after a listener is supposed to be removed, but this leads to verbose tests (read: brittle.) It would be way more efficient if I could just confirm the -= was invoked and move on.

@BrannonKing
Copy link

I, too, would like to vote for this item. Triggering a callback when an event is subscribed to -- that would be fantastic.

@grokys
Copy link

grokys commented Jul 16, 2015

👍 any movement on this?

@RomainHautefeuille
Copy link

Same here. I would like to be able to verify that add or remove has been called whith a specific handler.

@bigmealy
Copy link

I've just tried to do this very thing in Moq, and was sad when it didn't work. I was trying to use Verify to see if my system under test had subscribed to an event in my dependency.
In all other aspects so far, Moq rules!

@duffers20
Copy link

This feature would be incredibly useful in the project I'm working on just now.

Its a shame that it hasn't been implemented as I agree with bigmealy - Moq is awesome!

@kzu
Copy link
Member

kzu commented Oct 29, 2015

Almost always, you can test that by checking for the resulting state or
side effects.

i.e. cause the event to raise (or raise it yourself), and verify that the
callback wasn't invoked.

I've never really needed to verify add/remove event handlers, which is the
main reason this has continued to linger in the backlog.

On Wed, Oct 28, 2015 at 7:08 AM James Duffield notifications@github.com
wrote:

This feature would be incredibly useful in the project I'm working on just
now.

Its a shame that it hasn't been implemented as I agree with bigmealy - Moq
is awesome!


Reply to this email directly or view it on GitHub
#49 (comment).

@bigmealy
Copy link

Thanks for the reply kzu. In my case, the resulting state may or may not change depending on the EventArgs, which was causing my unit tests to start getting a bit lengthy. I then found this issue online and thought I would express an interest in this also. Thanks again.

@gtaylor1981
Copy link

gtaylor1981 commented Jul 25, 2016

This feature would be very useful to have, especially when the callback itself is only doing things to event handlers and cannot therefore be easily tested.

E.g. If I have a callback method for a ConnectionOnline event, which just attaches internal event handlers; and a method for a ConnectionOffline event, which just detaches the internal event handlers, my tests for ConnectionOnline/Offline then become dependent on the behavior of the internal event handlers. I have to write a lot of extra tests when all I want to say is something like:

mockConnection.Verify(x => x.DataArrived += null, Times.Once); // added

or

mockConnection.Verify(x => x.DataArrived -= null, Times.Once); // removed

I had a look at the source, and noticed that event invocations are a special case in AddActualInvocation.HandleIntercept(). If these event invocations were also added to the list of invocations in the context, might it make verification possible at least, as a first step?

Perhaps a syntax like that of protected methods might be needed, i.e. where the method name is passed manually:

mock.Events().Verify("add_DataArrived")

or even

mock.Events().VerifyAdded(nameof(mockConnection.DataArrived))

It seems this is one of the few things that Moq does not (yet ;) support. After all, adding/removing events are basically method calls to a mock, it would be great to be able to verify that they occurred like any other method on the mock.

@kzu
Copy link
Member

kzu commented Jul 25, 2016

They are a bit more than just methods. I'd suggest you try to manually
create a derived class that overrides event add/remove on a base class
(specially if it was not coded with overridability in mind).

Remember: Moq just automates what you can do manually yourself. In this
case, you can implement explicit methods add/remove for an interface events

On Mon, Jul 25, 2016, 7:49 AM gilesmeddowstaylor notifications@github.com
wrote:

This feature would be very useful to have, especially when the callback
itself is only doing things to event handlers and cannot therefore be
easily tested.

E.g. If I have a callback method for a ConnectionOnline event, which just
attaches internal event handlers; and a method for a ConnectionOffline
event, which just detaches the internal event handlers, my tests for
ConnectionOnline/Offline then become dependent on the behavior of the
internal event handlers. I have to write a lot of extra tests when all I
want to say is something like:

mockConnection.Verify(x => x.DataArrived += null, Times.Once); // added

or
mockConnection.Verify(x => x.DataArrived -= null, Times.Once); // removed

After all, adding/removing events are basically method calls to a mock, it
would be great to be able to verify that they occurred like any other
method on the mock.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#49 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAKW67PX5iXathkDoZnYF-85L1lenyJQks5qZJSzgaJpZM4Ar5pW
.

/kzu from mobile

@stakx stakx changed the title Has Verify of EventHandlers Addition been implemented? Implement verification of event handler attaches and detaches (something like mock.Verify(m => m.Event += callback)) Jul 17, 2017
@stakx stakx added this to the v4.9.0 milestone Dec 8, 2017
@stakx stakx removed this from the v4.9.0 milestone Feb 26, 2018
@stakx
Copy link
Contributor

stakx commented Jul 13, 2018

Closing this dormant issue, but marking it as "unresolved" so it can be easily found again. Please see #642 for details. If you'd like to pick this up and work on it, please post here briefly and we'll see what we can do!

@stakx stakx closed this as completed Jul 13, 2018
@Stannieman
Copy link

I agree that "is an event attached or detached" can be checked in other ways, but most of the times this is not convenient and also it blocks VerifyNoOtherCalls.
Cause VerifyNoOtherCalls DOES complain that something happened to the property, yet there's no way to make it ignore the events.

@stakx
Copy link
Contributor

stakx commented Apr 19, 2019

@Stannieman: Agreed, the whole event story is a little unsatisfactory at the moment.

I've recently refactored Moq internals to make delegate-based setup/verification expressions easier to deal with (mock => mock.Event += null falls into that category), so it should now be a lot easier to add new SetupAdd, SetupRemove, VerifyAdd and VerifyRemove methods. (It'll still be important to ensure backwards compatibility though.)

There's currently a PR for the setup side of things, we should be able to proceed with that as soon as Moq version 4.11 proper has been released. Accompanying verification methods would be the next logical step.

But someone will obviously have to do all that work. ;-)

@Stannieman
Copy link

Maybe in a couple of weeks I'll have time to look into it :) Though I don't know the code base so it'll be baby steps.

@stakx
Copy link
Contributor

stakx commented Apr 19, 2019

Baby steps are no problem at all. If you are interested in getting involved, there'll be a way. In the meantime, you can keep an eye on #693.

@stakx
Copy link
Contributor

stakx commented Sep 5, 2019

SetupAdd, SetupRemove, VerifyAdd, and VerifyRemove have been added to Moq's API in version 4.13.0, so I'm removing the unresolved label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests