Reputation: 63
in WPF, I am trying to use moq to raise an event that has an async listener hooked to it:
My code:
public class Provider
{
private IService _service
public Provider(IService service)
{
_service = service;
_service.OnResultsChanged += ChangeResults;
}
private async void ChangeResults(List resultsAdded)
{
await Task.Run(() => HasResults = true;)
}
}
For simplification, i've set hasresults to true, but I am really adding items to a list and as this operation could take a while, I am doing it in a new task. In my test, the following fails, as it doesn't wait for the DoSomething execution:
My test:
[Test]
public void Test()
{
//Arrange
var serviceMock = new Mock<IService>();
var systemUnderTest = new Provider(serviceMock .Object);
//Act
serviceMock.Raise(mock => mock.OnResultsChanged += null);
//Assert
Assert.IsTrue(systemUnderTest.HasResults);
}
is it possible to tell mock.raise to await the execution of my event listener?
Thanks!
Upvotes: 5
Views: 1928
Reputation: 247088
You can convert the test to be async as well and await a delayed task to allow the async event handler to perform its functionality.
The following example uses a delay in the even handler to simulate a potential long running task.
public interface IService {
event EventHandler OnResultsChanged;
}
public class Provider {
private IService _service;
public Provider(IService service) {
_service = service;
_service.OnResultsChanged += ChangeResults;
}
private async void ChangeResults(object sender, EventArgs e) {
await Task.Delay(200); //<-- simulate delay
await Task.Run(() => HasResults = true);
}
public bool HasResults { get; set; }
}
By converting the test to async and waiting for the raised event, the assertion was able to be asserted.
[TestClass]
public class MyTestClass {
[TestMethod]
public async Task Test() {
//Arrange
var serviceMock = new Mock<IService>();
var systemUnderTest = new Provider(serviceMock.Object) {
HasResults = false
};
//Act
serviceMock.Raise(mock => mock.OnResultsChanged += null, EventArgs.Empty);
await Task.Delay(300); //<--wait
//Assert
Assert.IsTrue(systemUnderTest.HasResults);
}
}
Upvotes: 5