简体   繁体   中英

Extension method to assert an event is raised in c#

Right now I'm doing this

bool didFire = false;
_viewModel.SomethingChanged = () => didFire = true;

_viewModel.SomeProperty = SomeValue;
Assert.IsTrue(didFire);

This has drawbacks :

  • The setup is ugly and long.
  • I need to reset didFire to false manually every time I make multiple calls, for example if I want to test the event is fired in certain cases but not always, following a certain scenario. This is prone to error since forgetting it might break the test.
  • With many events/callbacks/situations, this leads to even more boilerplate code for testing simple events.

So like any decent programmer would do, after seeing myself repeating the same task, I wanted to store it in a function.

The best idea I came up with is putting this in an Assert extension method but I couldn't find a decent way, either myself or online, to make it work and still be nice.

Ideally, I'm looking for something that would work as follows

Assert.WillBeRaised(_viewModel.SomethingChanged);
_viewmodel.SomeProperty = SomeValue;

or, maybe just the other way around

_viewmodel.SomeProperty = SomeValue;
Assert.WasRaised(_viewModel.SomethingChanged);

And this is where my problem lies, someone must be listening before the event is raised, and the assert must be done afterwards. So either way, I feel like I'll end up too many lines of code anyway.

Has anyone got some clean solution to this rather common problem?

You may want to have a look at Fluent Assertions .

With these you can do something like:

// this is the whole initialization
_viewModel.MonitorEvents();

// do test
_viewModel.SomeProperty = SomeValue;

// this is the whole assertion
_viewModel.ShouldRaise("SomethingChanged");

You can extend this to check for the arguments passed to the event handler etc:

_viewModel.ShouldRaise("SomethingChanged")
          .WithSender(_viewModel)
          .WithArgs<SomethingChangedEventArgs(e => e.Name == "SomeValue");

You can write it like this:

    public static void WillBeRaised(Action<Action> attach, Action act)
    {
        bool called = false;
        attach(() => called = true);
        act();
        Assert.IsTrue(called);
    }

And usage:

   WillBeRaised(
        x => _viewmodel.SomethingChanged += x, 
        () => _viewmodel.SomeProperty = SomeValue);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM