RaiseAsync()
must be used only for events with async handlers (returning Task
)Property | Value |
---|---|
Rule ID | PosInfoMoq2019 |
Title | RaiseAsync() must be used only for events with async handlers (returning Task ) |
Category | Compilation |
Default severity | Error |
Mock<T>.RaiseAsync()
must only be used with events whose delegate type returns Task
(i.e., async events).
Using RaiseAsync()
on events whose handlers return void
(or any non-Task
type) is invalid.
Moq provides RaiseAsync()
to trigger asynchronous events. This requires that the event delegate returns Task
(or Task<T>
).
If the event delegate returns void
(like EventHandler
or EventHandler<T>
), RaiseAsync()
is not appropriate and will cause runtime issues.
// Async event delegate
public delegate Task AsyncEventHandler(object sender, EventArgs e);
// Classic sync delegates (return void)
public delegate void VoidEventHandler(object sender, EventArgs e);
public class DataEventArgs : EventArgs { public int Value { get; } public DataEventArgs(int v) => Value = v; }
public class Service
{
public event AsyncEventHandler AsyncChanged; // returns Task
public event EventHandler SyncChanged; // returns void
public event EventHandler<DataEventArgs> SyncDataChanged; // returns void
}
var serviceMock = new Mock<Service>();
// Use RaiseAsync with async event (Task-returning delegate)
await serviceMock.RaiseAsync(s => s.AsyncChanged += null, EventArgs.Empty);
var serviceMock = new Mock<Service>();
// EventHandler returns void — using RaiseAsync is invalid
await serviceMock.RaiseAsync(s => s.SyncChanged += null, EventArgs.Empty); // ❌
// EventHandler<T> returns void — using RaiseAsync is invalid
await serviceMock.RaiseAsync(s => s.SyncDataChanged += null, new DataEventArgs(42)); // ❌
void
, use Raise()
instead of RaiseAsync()
.Task
-returning delegate, for example AsyncEventHandler
.// Using Raise() for void-returning events
serviceMock.Raise(s => s.SyncChanged += null, EventArgs.Empty);
serviceMock.Raise(s => s.SyncDataChanged += null, new DataEventArgs(42));
// Using RaiseAsync() for Task-returning events
await serviceMock.RaiseAsync(s => s.AsyncChanged += null, EventArgs.Empty);
Do not suppress this rule.
If disabled, Moq may throw a runtime exception (NullReferenceException
) due to a known bug when RaiseAsync()
is used on non-async events,
instead of providing a clear error message.
Reference: https://github.com/devlooped/moq/issues/1568