[-InsertNameHere-]
[-InsertNameHere-]
CC#
Created by [-InsertNameHere-] on 3/9/2025 in #help
✅ Async void method testing in xUnit
In WinForms, it's required to use async void for event handlers like button clicks due to its synchronous nature. However, when trying to test an event handler like the one below, how can I indirectly "await" async void for proper method execution. Async void method:
c#
internal async void HandleSubmit_Clicked(object? sender, EventArgs e)
{
try
{
bool Valid = await ValidFormAsync();
if (Valid)
{
_dataForm.OnSubmissionComplete(this, new SubmissionCompletedEventArgs(_dataForm.GetData(), _dataForm.Mode));
SubmissionCompleted?.Invoke(this, new SubmissionCompletedEventArgs(_dataForm.GetData(), _dataForm.Mode));
}
}
catch (Exception ex)
{
_logger.LogError("Submission Failed due to: {Exception}", ex.Message);
_dataForm.ShowMessageBox("Submission Failed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

protected virtual async Task<bool> ValidFormAsync()
{
_logger.LogCritical("ValidFormAsync is running in parent. Child must override it.");
await Task.Delay(100);
return true;
}
c#
internal async void HandleSubmit_Clicked(object? sender, EventArgs e)
{
try
{
bool Valid = await ValidFormAsync();
if (Valid)
{
_dataForm.OnSubmissionComplete(this, new SubmissionCompletedEventArgs(_dataForm.GetData(), _dataForm.Mode));
SubmissionCompleted?.Invoke(this, new SubmissionCompletedEventArgs(_dataForm.GetData(), _dataForm.Mode));
}
}
catch (Exception ex)
{
_logger.LogError("Submission Failed due to: {Exception}", ex.Message);
_dataForm.ShowMessageBox("Submission Failed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

protected virtual async Task<bool> ValidFormAsync()
{
_logger.LogCritical("ValidFormAsync is running in parent. Child must override it.");
await Task.Delay(100);
return true;
}
The test:
c#
[Fact]
public void HandleSubmit_Clicked_RaisesSubmissionCompletedEvent()
{
// Arrange
_presenterTemplate = new DataFormPresenterTemplate(_dataFormTemplate, _testLogger);

bool eventRaised = false;
void eventHandler(object? sender, SubmissionCompletedEventArgs args)
{
eventRaised = true;
}
_presenterTemplate.SubmissionCompleted += eventHandler;

// Act
_presenterTemplate.HandleSubmit_Clicked(null, EventArgs.Empty);

// Assert
Assert.True(eventRaised);

// Cleanup
_presenterTemplate.SubmissionCompleted -= eventHandler;
}
c#
[Fact]
public void HandleSubmit_Clicked_RaisesSubmissionCompletedEvent()
{
// Arrange
_presenterTemplate = new DataFormPresenterTemplate(_dataFormTemplate, _testLogger);

bool eventRaised = false;
void eventHandler(object? sender, SubmissionCompletedEventArgs args)
{
eventRaised = true;
}
_presenterTemplate.SubmissionCompleted += eventHandler;

// Act
_presenterTemplate.HandleSubmit_Clicked(null, EventArgs.Empty);

// Assert
Assert.True(eventRaised);

// Cleanup
_presenterTemplate.SubmissionCompleted -= eventHandler;
}
Any ideas on how to solve this?
30 replies