Skip to content

Instantly share code, notes, and snippets.

@HEskandari
Created January 3, 2014 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • 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();
}
}
}
@shiftkey
Copy link

shiftkey commented Jan 3, 2014

As @JakeGinnivan suggested

  1. you need to do the async Task or async void on the test method - and await the method inside
  2. mockService.Received().Calculate() is how you check a specific method was called

@shiftkey
Copy link

shiftkey commented Jan 3, 2014

Or you can get the raw data about mocks by calling mockService.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