Search code examples
unit-testingtddtask-parallel-libraryasync-awaitsystem.reactive

How can I unit test code that contain Task.Delay?


How can I unit test component that has an await Task.Delay without really having to wait for it.

For example,

public void Retry()
{
    // doSomething();
    if(fail)
       await Task.Delay(5000);
}

I need to test the failure branch but I do not want my test to wait for 5 seconds.

Is there anything like rx virtual time-based scheduling available in task parallel library?


Solution

  • A timer is just another form of external dependency. The only difference is that it depends on the clock instead of a database. And like any other external dependency, it makes testing hard; the answer, therefore, is to improve the design until it's easy to test.

    Following the Dependency Injection principle suggests that you should pass the timer in on the object's constructor, which enables you to inject a test stub instead of relying on a real timer.

    Note how this can improve your design. In many cases, the timeout period varies based on who's calling. This moves the responsibility for establishing the timeout period to the layer of your application that's waiting on it. That is the layer that should understand how long it's willing to wait.