Async Tests with NSubtitute and XUnit are actually pretty straight forward:
public interface IA
{
Task<int> DoSomething();
}
called by:
public class IAmUnderTest
{
public async Task<int> GetInt(IA a)
{
return await a.DoSomething();
}
}
Because Async methods just return tasks, all you need to do to mock DoSomething() with NSubstitute is use Task.FromResult(). Then the calling code gets a task back that it can still await and get back the integer result.
So mocking it with NSubstitute looks like this:
public class ATest
{
[Fact]
public void DoesSomething()
{
var dependency = Substitute.For<IA>();
dependency.DoSomething().Returns(Task.FromResult(1));
var target = new IAmUnderTest();
var id = target.GetInt(dependency).Result;
id.Should().Be(1);
}
}
Adding a little extra by making the test async:
public class ATest
{
[Fact]
public async Task DoesSomethingAsync()
{
var dependency = Substitute.For<IA>();
dependency.DoSomething().Returns(Task.FromResult(1));
var target = new IAmUnderTest();
var id = await target.GetInt(dependency);
id.Should().Be(1);
}
}
The latter is favoured over the former when testing async methods.
Credit to: https://www.garethrepton.com/Unit-Testing-async-methods/#:~:text=Because%20Async%20methods%20just%20return%20tasks%2C%20all%20you,So%20mocking%20it%20with%20NSubstitute%20looks%20like%20this%3A