Skip to content

Instantly share code, notes, and snippets.

@HEskandari
Created January 3, 2014 09:46
Show Gist options
  • Save HEskandari/8235481 to your computer and use it in GitHub Desktop.
Save HEskandari/8235481 to your computer and use it in GitHub Desktop.
NSubstitute and Async
using System.Threading.Tasks;
using NSubstitute;
using NUnit.Framework;
namespace ClassLibrary1
{
public interface ICalculationServiceAsync
{
Task Calculate();
}
public class SystemUnderTest
{
private readonly ICalculationServiceAsync _service;
public SystemUnderTest(ICalculationServiceAsync service)
{
_service = service;
}
public async void DoSomethingAsync()
{
await _service.Calculate();
}
}
[TestFixture]
public class AsyncTest
{
[Test]
public void Can_await_on_async_mocks()
{
var mockService = Substitute.For<ICalculationServiceAsync>();
var sut = new SystemUnderTest(mockService);
sut.DoSomethingAsync();
mockService.Calculate().ReceivedCalls();
}
}
}
@fluffynuts
Copy link

awaiting on the method projected by Received() will be a bit of a fail -- that projection returns null, so await throws a null dereference exception as it's trying to do something with the resultant task. So don't do (1).
(2) is arduous -- traversing the ReceivedCalls() output collection and doing the work for NSubstitute is, well, arduous. I'd recommend another approach over (2): take advantage of Received.InOrder:

Received.InOrder(async () =>
{
    await mockService.Calculate();
});

Or a shorter form without the braces. Since you probably had to mock out a resolved task to return from the Calculate method, this works just fine -- and you can easily use other NSubstitute constructs like Arg.Any<T>() without having to futz about with RecievedCalls(). Hope this helps (:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment