john doe
john doe

Reputation: 9660

Unit Testing Async Methods Using NUnit and C#

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

Answers (1)

Igor
Igor

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

Related Questions