# Raising Events from Mock Objects

## Raising events

Sometimes it is necessary to raise events declared on the types being substituted for. Consider the following example:

```csharp

public interface IEngine {
    event EventHandler Idling;
    event EventHandler<LowFuelWarningEventArgs> LowFuelWarning;
    event Action<int> RevvedAt;
}

public class LowFuelWarningEventArgs : EventArgs {
    public int PercentLeft { get; private set; }
    public LowFuelWarningEventArgs(int percentLeft) {
        PercentLeft = percentLeft;
    }
}
```

Events are “interesting” creatures in the .NET world, as you can’t pass around references to them like you can with other members. Instead, you can only add or remove handlers to events, and it is this add handler syntax that NSubstitute uses to raise events.

```csharp
var wasCalled = false;
engine.Idling += (sender, args) => wasCalled = true;

//Tell the substitute to raise the event with a sender and EventArgs:
engine.Idling += Raise.EventWith(new object(), new EventArgs());

Assert.True(wasCalled);
```

In the example above we don’t really mind what sender and `EventArgs` our event is raised with, just that it was called. In this case NSubstitute can make our life easier by creating the required arguments for our event handler:

```
engine.Idling += Raise.Event();
Assert.True(wasCalled);
```

### Raising events when arguments do not have a default constructor <a href="#raising-events-when-arguments-do-not-have-a-default-constructor" id="raising-events-when-arguments-do-not-have-a-default-constructor"></a>

NSubstitute will not always be able to create the event arguments for you. If your event args do not have a default constructor you will have to provide them yourself using `Raise.EventWith<TEventArgs>(...)`, as is the case for the `LowFuelWarning` event. NSubstitute will still create the sender for you if you don’t provide it though.

```csharp
engine.LowFuelWarning += (sender, args) => numberOfEvents++;

//Raise event with specific args, any sender:
engine.LowFuelWarning += Raise.EventWith(new LowFuelWarningEventArgs(10));
//Raise event with specific args and sender:
engine.LowFuelWarning += Raise.EventWith(new object(), new LowFuelWarningEventArgs(10));

Assert.AreEqual(2, numberOfEvents);
```

### Raising `Delegate` events <a href="#raising-delegate-events" id="raising-delegate-events"></a>

Sometimes events are declared with a *delegate* that does not inherit from `EventHandler<T>` or `EventHandler`. These events can be raised using `Raise.Event<TypeOfEventHandlerDelegate>(arguments)`. NSubsitute will try and guess the arguments required for the delegate, but if it can’t it will tell you what arguments you need to supply.

The following examples shows raising an `INotifyPropertyChanged` event, which uses a `PropertyChangedEventHandler` delegate and requires two parameters.

```csharp
var sub = Substitute.For<INotifyPropertyChanged>();
bool wasCalled = false;
sub.PropertyChanged += (sender, args) => wasCalled = true;

sub.PropertyChanged += Raise.Event<PropertyChangedEventHandler>(this, new PropertyChangedEventArgs("test"));

Assert.That(wasCalled);
```

### Raising `Action` events <a href="#raising-action-events" id="raising-action-events"></a>

In the `IEngine` example the `RevvedAt` event is declared as an `Action<int>`. This is another example of a delegate event, and we can use `Raise.Event<Action<int>>()` to raise our event.

```csharp
int revvedAt = 0;;
engine.RevvedAt += rpm => revvedAt = rpm;

engine.RevvedAt += Raise.Event<Action<int>>(123);

Assert.AreEqual(123, revvedAt);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dotnetweb30-ke.gitbook.io/ke/verification/automated-testing-frameworks-tools-libraries/nsubstitute/raising-events-from-mock-objects.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
