Reader Level:
ARTICLE

Unit Testing Async Marked Methods Using Mock Library

Posted by Amit Choudhary Articles | Testing January 06, 2014
This article will provides you with a solution to the problem of using Nunit to do unit testing of a method marked with async.
  • 2
  • 0
  • 3989

Have you ever tried unit testing a method marked with async? There’s a known problem with unit testing methods marked Async. When Nunit attempts to run the test with mocked Async methods it goes into an infinite wait. There are many explanations on the internet of why it happens and giving you solutions and work arounds. This article will provide you with another solution.

Let’s start and setup a test project to reproduce the problem. So first we need a library that contains the methods marked with the Async keyword.

First we need the marker interface:

IHttpDownloader.cs
 

public interface IHttpDownloader

{

    Task<string> DownloadContentAsync(Uri httpUri);

}

  
Implementation

HttpDownloader.cs
 

public class HttpDownloader : IHttpDownloader

{

    public async Task<string> DownloadContentAsync(Uri httpUri)

    {

        RawHttpDownloader downloader = new RawHttpDownloader();

 

       return await downloader.DownloadAsync(httpUri);

    }

}

Helper class

RawHttpDownloader.cs
 

public class RawHttpDownloader

{

    public async Task<string> DownloadAsync(Uri httpUri)

    {

        return string.Format("Dummy downloaded string from {0}", httpUri.AbsolutePath);

    }

}

Now let's write a unit test to test this method for a positive scenario. Here I have used the Nunit to write the tests:
 

[TestFixture]

public class HttpDownloaderTest

{

    [Test]

    public void DownloadContentAsync_ValidHttpAddress_ReturnsData()

    {

        var repository = new MockRepository();

        var httpUri = new Uri("http://www.google.com/about");

        var downloaderStub = repository.Stub<IHttpDownloader>();

        // setup

        var task = new Task<String>(

            () => { return "test string"; });

        downloaderStub.Expect(s => s.DownloadContentAsync(httpUri)).Return(task);

        // act

        repository.ReplayAll();

        var restult = downloaderStub.DownloadContentAsync(httpUri);

        Assert.IsNotNull(restult.Result);

        repository.VerifyAll();

    }

}

  
If you try to run this test then It will go into an wait forever:

Helper class

The problem is caused by the Nunit framework since it doesn’t support methods marked with the Async keyword for tests. So it continues waiting for the asynchronous method and it actually never invokes the Task returned into the start state.

Solution


Since the Nunit doesn’t actually invoke the underlying task to the start state you need to do is to just Start the task manually.

Unit testing

Download the complete sample from here.

COMMENT USING

Trending up