How to test in xunit that Event was raised?
Asked Answered
W

1

6

I defined simple event in class like that

class Request 
{
   protected virtual void OnStateChanged()
   {
      StateChanged?.Invoke(this, EventArgs.Empty);
   }

   public event EventHandler StateChanged;

   public void Approve()
   {
      OnStateChanged();
   }

}

how do I xunit that this event were raised ?

I tried one line event handler implementation

bool eventRaised = false;
request.StateChanged += (obj, eventArgs) => eventRaised = true;
request.Approve();
Assert.True(eventRaised);

it works, but is there any better approach ? I did not figure out, how to use Assert.Raises()

Whirlpool answered 29/3, 2020 at 17:18 Comment(3)
is there any better approach - what push you for a better? What missing in current approach? We can suggest multiple different approaches by using different frameworks and start holy testing frameworks war ;)Eurystheus
It's totally okay, but it is 4 lines, I was thinking something like Assert.Raises(request.StateChanged) :D Also at first thought I thought I'd have to create a new method, now it's only 4 lines (but it could be one :-).Whirlpool
Wrap it with a method and use it as one line ;)Eurystheus
H
6

That is the commonly suggested approach

The following example however, shows how to use Assert.Raises() to test your provided class's event

var request = new Request();

var evt = Assert.Raises<EventArgs>(
    h => request.StateChanged += h,
    h => request.StateChanged -= h,
    () => request.Approve());

Assert.NotNull(evt);
Assert.Equal(request, evt.Sender);
Assert.Equal(EventArgs.Empty, evt.Arguments);

However, your event handler would need to be the generic delegate

public event EventHandler<EventArgs> StateChanged;

instead of just EventHandler in order for Assert.Raises to work as expected.

Habana answered 29/3, 2020 at 19:5 Comment(1)
OK, but what if I cannot change the type of the event from the non-generic EventHandler because I'm implementing an interface? (e.g. ICommand.CanExecuteChanged)?Hibbs

© 2022 - 2024 — McMap. All rights reserved.