chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
Hi. I have an interface I want to mock, and it contains lots of events. The class I want to test subscribes to all of these events. I'd like to test each of these events in a separate test method. Because the setup of the event subscriptions is lengthy, I'd like to break it out into a common function. Then I'd like to fire selected events in individual test methods, but I can't seem to figure out how to do this.

Here's my example interface:

public interface IView
{
    string myprop { get; set; }
    event EventHandler EventA;
    event EventHandler EventB;
    event EventHandler EventC;
    event EventHandler EventD;
    // etc.
}


And in my test methods I'd like to do this...

IView view = GetMyMockedView();
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
    // set the view expectations including the subscriptions
}

// the class internally subscribes to the events
MyClassUnderTest c = new MyClassUnderTest(view);

// I want to test eventC here
MockedEvent myEventC = SomehowGetReferenceToMockedEventC();
myEventC.Fire(null, null);



I'd like to break out the expectation setting (with event subscriptions) in one place, then test EventC here without testing the other events. Can I do this? It seems like the only way to get a reference to a mocked event is to use RecorderManager.LastMockedEvent, which makes it look difficult to break my setup code out of each individual test method.

My current attempts look dumb because the same 20 lines of setup code is duplicated in each test method. :(


thanks,
Chris
asked by cfarmerga (1.8k points)

4 Answers

0 votes
Hi Chris,

I'd like to break out the expectation setting (with event subscriptions) in one place, then test EventC here without testing the other events. Can I do this?


Yes you can.
However, this will be easier using Reflective Mocks, mainly because Reflective is not strongly typed and uses strings to set expectations.
(It can be done in Natural but you'll have to resort to using reflection which is more complex)

Look at the following example:
[Test]
[VerifyMocks]
public void EventTestReflection()
{
    MockObject mockView;
    MockedEvent handleEvent = MockEventFiring(out mockView, "EventA", "AFired");
        
    IView view = mockView.Object as IView;
    MyClassUnderTest target = new MyClassUnderTest(view);
    target.SetupEvent();

    handleEvent.Fire(null, null);
}

[Test]
[VerifyMocks]
public void EventTestReflectionB()
{
    MockObject mockView;
    MockedEvent handleEvent = MockEventFiring(out mockView, "EventB", "BFired");

    IView view = mockView.Object as IView;
    MyClassUnderTest target = new MyClassUnderTest(view);
    target.SetupEvent();

    handleEvent.Fire(null, null);
}

private static MockedEvent MockEventFiring(out MockObject mockView,string EventName,string EventHandler)
{
    Mock mockTested = MockManager.Mock<MyClassUnderTest>(Constructor.NotMocked);
    mockTested.ExpectCall(EventHandler).Args(null, null);

    mockView = MockManager.MockObject(typeof(IView));
    mockView.Strict = false;
    return mockView.ExpectAddEvent(EventName);
}


:!: Pay attention that I've set the view strictness mode to false. This is necessary since i assume that your tested class registers on all events which means that there will be several unexpected calls Add_Event in each test.

I hope this example is in the spirit of what you needs
let me know if you need any clarifications or if this is not what you've needed
answered by lior (13.2k points)
0 votes
This helps a lot, but mostly in other ways than to help with my original question. I think the key to my specific issue here was simply your hint to just set strict to false. I guess I just didn't understand how to get into that mode where arbitrary calls are okay but explicitly set expectations still need to be fulfilled. I then saw how to do what I needed to do with the natural mocks stuff (RecorderManager.CreateMockedObject<IView>(StrictFlags.ArbitraryMethodsAllowed);), which I think I prefer over the reflective mocks.

thanks!
Chris
answered by cfarmerga (1.8k points)
0 votes
As long as it was helpful :D

In any case I would like to thank you for your post.
And if you encounter any other problem let me know
answered by lior (13.2k points)
0 votes
I just want to clarify that the reason I wanted to break out the event subscription stuff into a common subroutine was that I didn't know how to turn off strict mode. I thought I'd have to mock subscribe to every event for every test, and that was truly ugly. Now I can be strict and explicit in a couple tests and test higher-level functionality in the other tests without all the subscription clutter.

thanks again,
chris
answered by cfarmerga (1.8k points)
...