Search code examples
c#unit-testingrhino-mocks

Mock firing an event from 3rd party class


I'm trying to write an interaction test that needs to fire an event within a class I do not own (C# 4.0 environment):

public class DoNotOwn
{
  public event EventHandler<SomeEventArgs> SomeEvent;
}

DoNotOwn does does not provide a protected OnSomeEvent to override and does not implement any interfaces or have any virtual members. The class under test has a DoNotOwn instance within it and subscribes to SomeEvent:

public class ClassUnderTest
{
  private DoNotOwn x;

  public SetupDoNotOwn(DoNotOwn arg)
  {
    x = arg;
    x.SomeEvent += MyEventHandler;
  }

  protected void MyEventHandler(object sender, SomeEventArgs args)
  {
    // Does work that needs to be tested
  }
}

I'm aware that I could make a separate method available to the test that does the inner guts of MyEventHandler, but I'm wondering if there is a way to have a fake DoNotOwn fire that event.

I have RhinoMocks available in the environment. My attempts at raising that event either result in no event firing or a complaint of "Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual ... method)", such as with:

DoNotOwn stub = MockRepository.GenerateStub<DoNotOwn>();
stub.SomeEvent += null;
IEventRaiser eventer = LastCall.GetEventRaiser(); // InvalidOperationException

I'd be willing to try Moq. Typemock not in the budget.


Solution

  • The problem isn't that you don't have "protected OnSomeEvent". That is usually the naming for handling a event, not firing it.

    If you didn't understand Chris' answer, he says that you (since you don't have an abstraction "IDoNotOwn" of DoNotOwn) you can instead create a DoNotOwnWrapper that implements a IDoNotOwnWrapper.

    interface IDoNotOwnWrapper
    {
        event EventHandler<SomeEventArgs> SomeEvent;
    }
    
    class DoNotOwnWrapper : IDoNotOwnWrapper
    {
        DoNotOwn _internal;
        public DoNotOwnWrapper()
        {
             _internal = new DoNotOwn();
             _internal.SomeEvent += SomeEvent;
        } 
        event EventHandler<SomeEventArgs> SomeEvent;
    }
    

    Then you can easily depend on the Wrapper class instead and mock its Abstract interface in the mocking framework.

    I would definitely recommend you using Moq because of its crisp syntax, but both RhinoMock and Moq will do the trick.