views:

432

answers:

1

I am trying to write unit tests for a bit of code involving Events. Since I need to raise an event at will, I've decided to rely upon RhinoMocks to do so for me, and then make sure that the results of the events being raised are as expected (when they click a button, values should change in a predictable manner, in this example, the height of the object should decrease)

So, I do a bit of research and realize I need an Event Raiser for the event in question. Then it's as simple as calling eventraiser.Raise(); and we're good.

The code for obtaining an event raiser I've written as is follows (written in C#) (more or less copied straight off the net)

            using (mocks.Record())
        {
            MyControl testing = mocks.DynamicMock<MyControl>();
            testing.Controls.Find("MainLabel",false)[0].Click += null;
            LastCall.IgnoreArguments();
            LastCall.Constraints(Rhino.Mocks.Constraints.Is.NotNull());
            Raiser1 = LastCall.GetEventRaiser();
        }

I then test it as In playback mode.

            using (mocks.Playback())
        {
            MyControl thingy = new MyControl();
            int temp=thingy.Size.Height;
            Raiser1.Raise();
            Assert.Greater(temp, thingy.Size.Height);
        }

The problem is, when I run these tests through NUnit, it fails. It throws an exception at the line testing.Controls.Find("MainLabel",false)[0].Click += null; which complains about trying to add null to the event listener. Specifically, "System.NullReferenceException: Object Reference not set to an instance of the Object"

Now, I was under the understanding that any code under the Mocks.Record heading wouldn't actually be called, it would instead create expectations for code calls in the playback. However, this is the second instance where I've had a problem like this (the first problem involved classes/cases that where a lot more complicated) Where it appears in NUnit that the code is actually being called normally instead of creating expectations. I am curious if anyone can point out what I am doing wrong. Or an alternative way to solve the core issue.

+3  A: 

I'm not sure, but you might get that behaviour if you haven't made the event virtual in MyControl. If methods, events, or properties aren't virtual, then I don't think DynamicMock can replace their behaviour with recording and playback versions.

Personally, I like to define interfaces for the classes I'm going to mock out and then mock the interface. That way, I'm sure to avoid this kind of problem.

Don Kirkby
This sounds like the answer. The syntax above looks alright to me...
jpoh
Yep. That turns out to be the problem. Although how to get around it and raise the event anyway is the new problem, but I'll figure that part out.
Kurisu