Reputation: 9660
I am trying to unit test an async methods of a search query. The unit test is defined below:
[Test]
public async Task MyTest1()
{
var readyToScheduleQuery = new ReadyToScheduleQuery()
{
Facets = new List<Facet>()
{
new Facet()
{
Name = "Service Type",
Values = new List<FacetValue>()
{
new FacetValue()
{
Value = "SomeJob",
Selected = true
}
}
}
}
};
var result = readyToScheduleQuery.ExecuteAsync(_appointmentRespositoryStub);
Assert.IsNotNull(result);
}
The ExecuteAsync
method of readyToScheduleQuery is defined below:
internal async Task<ReadyToScheduleResult> ExecuteAsync(IAppointmentRepository appointments)
{
var query = await appointments.GetReadyToSchedule(this.Id, exclude: NotificationTags.Something);
The unit test just hangs up and never returns a result. Any ideas?
It hangs up if I do the following: (Note the Result
property at the end)
var result = readyToScheduleQuery.ExecuteAsync(_appointmentRespositoryStub).Result;
Upvotes: 1
Views: 1545
Reputation: 62213
You are missing an await. When writing your async/await you continue to call await on everything that is marked as async all the way down your callstack.
[Test]
public async Task MyTest1()
{
var readyToScheduleQuery = new ReadyToScheduleQuery()
{
Facets = new List<Facet>() { new Facet() { Name = "Service Type", Values = new List<FacetValue>() { new FacetValue() { Value = "SomeJob", Selected = true} } } }
};
// missing await
var result = await readyToScheduleQuery.ExecuteAsync(_appointmentRespositoryStub);
Assert.IsNotNull(result); // you will receive your actual expected unwrapped result here. test it directly, not the task.
}
This will hang.
var result = readyToScheduleQuery.ExecuteAsync(_appointmentRespositoryStub).Result;
See this previous answer from Stephen Cleary as to why that is. Here again that answer (refer to the link though in case it has changed since the writing of this answer).
You're running into the standard deadlock situation that I describe on my blog and in an MSDN article: the async method is attempting to schedule its continuation onto a thread that is being blocked by the call to Result.
In this case, your SynchronizationContext is the one used by NUnit to execute async void test methods. I would try using async Task test methods instead.
Upvotes: 3