Testing Events Using Rhino Mocks

There are possible more 'elegant' methods for the below but these are fairly well understandable by someone new to Rhino Mocks or mocking in general.

Testing Event Subscription

Sometimes we want to ensure that a given event has been subscribed to. The following example is essentially testing that when a new ViewModel is instantiated (the constructor accepts an IWorkPackageCoordinator as a dependency), that the events declared on the IWorkPackageCoordinator instance have been subscribed to (by the ViewModel instance). In other words: does the ViewModel subscribe to the IWorkPackageCoordinatorevents.

To test this we create a ViewModel and pass it a mock object that has been created for us by Rhino Mocks.

 

            MockRepository mocks = new MockRepository();
            IWorkPackageCoordinator mockWPC = (IWorkPackageCoordinator)mocks.StrictMock(typeof(IWorkPackageCoordinator));

            // Tell Rhino Mocks that we expect the following events to be subscriped to
            //  - we don't care about the actual delegate that is attached hence the
            // LastCall.IgnoreArguments();
            mockWPC.Downloading += null;
            LastCall.IgnoreArguments();

            mockWPC.Loading += null;   
            LastCall.IgnoreArguments();

            mockWPC.Processing += null;
            LastCall.IgnoreArguments();

            mockWPC.Saving += null;
            LastCall.IgnoreArguments();

            mocks.ReplayAll();

            new ViewModel(mockWPC);
           
            mocks.VerifyAll();  

 

Testing Event Raising\Handling

Another test that is useful is that the object we are testing performs some action when another object raises an event that it is subscribed to.

In the example below we want to test that when an IWorkPackageCoordinator raises it's Downloading event that the ViewModel in turn raises it's PropertyChanged event. We use a boolean eventRaised, and (using lambda syntax) create an anonymous event handler for the PropertyChanged event which sets eventRaised to true if the event is fired. We then tell out Rhino Mock object to raise the Downloading event (in this example with non specific event arguments 'EventArgs.Empty')

            var mockWPC = MockRepository.GenerateMock<IWorkPackageCoordinator>();
            var SUT = new ViewModel(mockWPC);

            bool eventRaised = false;

            SUT.PropertyChanged += (s, e) => { eventRaised = true; };

            // tell mock to raise event
            mockWPC.Raise(x => x.Downloading += null, this, EventArgs.Empty);

            Assert.IsTrue(eventRaised);

 

SHARE:

Understanding Lambda Expressions

Of all the additions to the C# language, lambda expressions are potentially the most confusing. Part of this might be due to the odd look of the syntax when you first see it or that a lot of the examples use single letters in the expressions.

The best way to start thinking about lambdas is to think of them simply as anonymous methods.

Suppose we have declared a Timer in a WinForms application as: Timer t = new Timer(); We now need to wire up the Timer's Tick event to some code that is to be executed when the Timer fires.

There are various ways to do this without using lambdas:

  1. Declare an explicit event handler method

    void t_Tick(object sender, EventArgs e)
    {
        textBox1.Text = DateTime.Now.ToString();
    }

    ...
    t.Tick +=new EventHandler(t_Tick); or using delegate inference t.Tick += t_Tick;

  2. Use an anonymous method

    t.Tick += delegate(object sender2, EventArgs e2)
    {
       textBox1.Text = DateTime.Now.ToString();
    };


To write the above using a lambda expression you could write:

t.Tick += (object sender2, EventArgs e2) => textBox1.Text = DateTime.Now.ToString();

Or using type inference:

t.Tick += (sender2, e2) => textBox1.Text = DateTime.Now.ToString(); 

These are examples of expression lambdas. Another type is the statement lambda which is similar but can contain multiple statements enclosed in braces; for example we could write the following:

t.Tick += (object sender2, EventArgs e2) =>
{
    textBox1.Text = DateTime.Now.Minute.ToString();
    textBox2.Text = DateTime.Now.Second.ToString();
};

Note: the => is typically read as "goes to".

Another Example

To print all numbers in a list of ints to a TextBox:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
numbers.ForEach(number => textBox1.Text += number.ToString());

To print all number from 6 and up:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
numbers.ForEach(number =>
{
    if (number > 5)
        textBox1.Text += number;
});

or:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
numbers.FindAll(number => number > 5).ForEach(number => textBox1.Text += number.ToString());

If you want to fill in the gaps in your C# knowledge be sure to check out my C# Tips and Traps training course from Pluralsight – get started with a free trial.

SHARE: