|
ms
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
raising/invoking eventsgeneral strategy for testing them. Say my button widget has a property in it's interface of: public event EventHandler Click; If I implement this as a Win Forms button, I know I can use the implemented buttons PreformClick() method to test it, but how can I do this more generically, just using the .Net event? For example, in the sample test code below, I think I want to do something like widgetHello.Click.Invoke(this, EventArgs.Empty); which doesn't even compile much less work. Thanks for the help - BH [Test] public void ClickEvent_CanBeDelegated_ToAnArbitraryMethod() { // arrange Assert.That(HelloMessage, Is.EqualTo(null)); var btnHello = new Button {Text = "Click Me"}; var widgetHello = new WinButton(btnHello); widgetHello.Click += delegate { SayHello(); }; // act btnHello.PerformClick(); // assert Assert.That(HelloMessage, Is.EqualTo("Hello World")); } There isn't a safe way of raising an arbitrary event. In this case,
one option might be to add an "internal" method that raises the event - for example (extending the typical protected virtual OnFoo method): public event EventHandler Foo; protected internal virtual void OnFoo() { if(Foo!=null) Foo(this,EventArgs.Empty); } then use the [InternalsVisibleTo] attribute to allow your test project access to the internal method. Your test project can now call OnFoo() to raise the event. This only works if you own the type, of course. Marc I'd like to be able to test Foo != null, and I don't understand the logic of
"Click' can only appear on the left hand side of += or -. Iis there another way to determiine if an event is null from another class? Thanks for sharing! BH public event EventHandler Click; protected internal virtual void OnClick() { if(Click!=null) Foo(this,EventArgs.Empty); } On Wed, 10 Dec 2008 17:05:45 -0800, Berryl Hesh <efing***@yahoo.com> wrote:
> I'd like to be able to test Foo != null, and I don't understand the That's exactly what an event is and does. If you "don't understand the > logic of > "Click' can only appear on the left hand side of += or -. logic" of that, then you probably don't really understand events themselves (see the C# specification or MSDN's discussion on the topic). Alternatively, if that restriction doesn't work for your intended design, then you shouldn't be using an event in the first place. > Iis there another Not unless you have control over the class implementing the event, and > way to determiine if an event is null from another class? explicitly expose that information via a property or method. The whole point of the event is that it encapsulates specific behavior, hiding the implementation from code outside the class where the event is declared. Frankly, there's a good chance that what you're trying to do is not a good way to design the code anyway. But, if you really feel that you need this, you need to either add a member to the class that will leak the event implementation to code outside the class, or you need to not use an event. Pete I understand the encapsulation side, ie, invoking the event. It's the
testing of whether its subscribed to that I don't grok. What I want to do here is be able to trigger an event, in a test, so I know it is doing what it should, especially after refactoring something. I also like to test that the event has been subscribed to in test code (less useful). I know I can provide hooks to do these things from the owning class, but then I have broken encapsulation to do so. Can you recommend a test framework for this? Show quoteHide quote "Peter Duniho" <NpOeStPe***@nnowslpianmk.com> wrote in message news:op.uly4bljx8jd0ej@petes-computer.local... > On Wed, 10 Dec 2008 17:05:45 -0800, Berryl Hesh <efing***@yahoo.com> > wrote: > >> I'd like to be able to test Foo != null, and I don't understand the >> logic of >> "Click' can only appear on the left hand side of += or -. > > That's exactly what an event is and does. If you "don't understand the > logic" of that, then you probably don't really understand events > themselves (see the C# specification or MSDN's discussion on the topic). > Alternatively, if that restriction doesn't work for your intended design, > then you shouldn't be using an event in the first place. > >> Iis there another >> way to determiine if an event is null from another class? > > Not unless you have control over the class implementing the event, and > explicitly expose that information via a property or method. > > The whole point of the event is that it encapsulates specific behavior, > hiding the implementation from code outside the class where the event is > declared. > > Frankly, there's a good chance that what you're trying to do is not a good > way to design the code anyway. But, if you really feel that you need > this, you need to either add a member to the class that will leak the > event implementation to code outside the class, or you need to not use an > event. > > Pete On Wed, 10 Dec 2008 17:26:36 -0800, Berryl Hesh <efing***@yahoo.com> wrote:
> I understand the encapsulation side, ie, invoking the event. It's the By design, events do not allow you to test that from outside the class.> testing of whether its subscribed to that I don't grok. > What I want to do here is be able to trigger an event, in a test, so I I don't understand why you feel the need to write tests that break > know > it is doing what it should, especially after refactoring something. I > also > like to test that the event has been subscribed to in test code (less > useful). I know I can provide hooks to do these things from the owning > class, but then I have broken encapsulation to do so. encapsulation. In OOP, encapsulation is everything. Surely you don't break encapsulation to test the rest of your code? The test should be testing the _encapsulated_ behavior of the class, because that's what matters to the client of the class. You can include, in your debug build, internal consistency checks in the class itself, but expecting a test harness to be able to do that kind of checking isn't correct. For an event, what you really should be testing is whether, after subscribing to it, your handler is called when the appropriate circumstances occur. Even if you could arbitrarily cause the event to be raised, you're not testing the part of the code that actually matters anyway. You need to test that your handler gets executed for real, when the real-world situation that would raise the event happens. For that, there's no need to break encapsulation. Pete The point is to find useful techniques for *maintaining* encapsulation
(including event driven behavior) while providing engineered tests for the entire codebase (including event driven behavior). Ayende / RhinoMocks provides support for this on interface events http://ayende.com/Wiki/How+to+raise+events+using+AAA+and+RR+syntax.ashx, and Osherove / TeamAgile has something here (http://weblogs.asp.net/rosherove/archive/2005/06/13/EventsVerifier.aspx Thanks On Thu, 11 Dec 2008 16:46:11 -0800, Berryl Hesh <efing***@yahoo.com> wrote:
> The point is to find useful techniques for *maintaining* encapsulation I'm afraid I don't understand how either of those examples relate to or > (including event driven behavior) while providing engineered tests for > the > entire codebase (including event driven behavior). > > Ayende / RhinoMocks provides support for this on interface events > http://ayende.com/Wiki/How+to+raise+events+using+AAA+and+RR+syntax.ashx, > and > Osherove / TeamAgile has something here > (http://weblogs.asp.net/rosherove/archive/2005/06/13/EventsVerifier.aspx elaborate on your question. My understanding of your question is that you want to know how to test using an event found in a production class. Neither of those examples do that. The first bypasses the production implementation of the event (they seem to have some kind of class that can mock interface implementations). The second uses an explicitly exposed implementation detail of the class implementing the event (i.e. it relies on a method in the class that is known specifically to raise the event). You can, as in the first example, use reflection to inspect anything in the class you want. The first example doesn't seem to do what you are asking for, but you can use similar techniques to inspect the state of the class being tested to verify whatever it is you want to verify, just as the tool being discussed there must do. Alternatively you can, as in the second example, just rely on the class that implements the event to provide you with a method that is used to raise the event, and just call that method. But, we've already explained that particular approach, so I don't see what that second example adds to the discussion. Pete
WPF Add-In: UriFormatException when trying to use SiteOfOrigin
Curious Legacy Code - methods containing nothing but a semi colon Validate DateTime debugging a service split with multiple blanks Find Row in a DataSet Class problem WPF: UserControl constructor executes when opening in designer Range Can a thread detect that the app is exiting? |
|||||||||||||||||||||||