kord
kord

Reputation: 1039

How to unit test a method that uses Task.WhenAll

Let's say we have the following class:

class SampleClass
{
    private readonly IList<int> _numberList = new List<int> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    public void MethodToBeTested()
    {
        Task.WhenAll(_numberList.Select(async number => { await Task.Run(() => { ProcessNumber(number); }); }));
    }

    private static void ProcessNumber(int number)
    {
        Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId} Number:{number}");
        Thread.Sleep(1000);
    }
}

and we add the following unit test:

[Test]
public void TestMethodToBeTested()
{
    var sampleClass = new SampleClass();
    _sampleClass.MethodToBeTested();
}

The problem is that when the test runs, it doesn't wait for the MethodToBeTested to finish the execution so the output varies. Is there any way to test the full run of this method using NUnit, without changing the method signature (from void to Task) ?

Upvotes: 3

Views: 3553

Answers (2)

Eduardo Luis Santos
Eduardo Luis Santos

Reputation: 496

Just in case someone has tasks that are using the network:

In theory, a unit test shouldn't have network calls, so you don't need to run the tasks. You can fake the calls (Task.FromResult(true)) but if you actually want to make a network call then consider the integration test.

Upvotes: 0

techvice
techvice

Reputation: 1301

Using GetAwaiter().GetResult() will make sure that an asynchronous call runs to completion. Read more about that approach vs await here

public void MethodToBeTested()
{
    Task.WhenAll(_numberList.Select(async number => { await Task.Run(() => { ProcessNumber(number); }); })).GetAwaiter().GetResult();
}

Upvotes: 1

Related Questions