Skip to content

Instantly share code, notes, and snippets.

@HEskandari
Created October 28, 2013 07:31
Show Gist options
  • Save HEskandari/7192698 to your computer and use it in GitHub Desktop.
Save HEskandari/7192698 to your computer and use it in GitHub Desktop.
[TestFixture]
public class MockingAsyncTask
{
[Test]
public async void can_mock_interface_methods_with_task_return()
{
var mock = NSubstitute.Substitute.For<ILongRunningOperation>();
var sut = new SystemUnderTest {Operaiton = mock};
await sut.Execute();
mock.DoSomething().ReceivedCalls();
}
public class SystemUnderTest
{
public ILongRunningOperation Operaiton { get; set; }
public async Task Execute()
{
await Operaiton.DoSomething();
}
}
public interface ILongRunningOperation
{
Task DoSomething();
}
}
@HEskandari
Copy link
Author

Test 'NServiceBus.Profiler.Tests.MockingAsyncTask.can_mock_interface_methods_with_task_return' failed: System.NullReferenceException : Object reference not set to an instance of an object.
AsyncTest.cs(39,0): at NServiceBus.Profiler.Tests.MockingAsyncTask.SystemUnderTest.d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
AsyncTest.cs(28,0): at NServiceBus.Profiler.Tests.MockingAsyncTask.<can_mock_interface_methods_with_task_return>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__0(Object state)
at NUnit.Core.AsyncSynchronizationContext.AsyncOperation.Invoke()
at NUnit.Core.AsyncSynchronizationContext.AsyncOperationQueue.InvokePendingOperations()
at NUnit.Core.AsyncSynchronizationContext.AsyncOperationQueue.InvokeAll()
at NUnit.Core.NUnitAsyncTestMethod.RunVoidAsyncMethod(TestResult testResult)

When changing the test method from async void to async Task I get a different exception:

Test 'NServiceBus.Profiler.Tests.MockingAsyncTask.can_mock_interface_methods_with_task_return' failed: NSubstitute.Exceptions.NotASubstituteException : NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For() and related methods.
at NSubstitute.Core.CallRouterResolver.ResolveFor(Object substitute)
at NSubstitute.Core.SubstituteFactory.GetCallRouterCreatedFor(Object substitute)
at NSubstitute.Core.SubstitutionContext.GetCallRouterFor(Object substitute)
at NSubstitute.SubstituteExtensions.GetRouterForSubstitute[T](T substitute)
at NSubstitute.SubstituteExtensions.ReceivedCalls[T](T substitute)
AddressTests.cs(173,0): at NServiceBus.Profiler.Tests.MockingAsyncTask.<can_mock_interface_methods_with_task_return>d__1.MoveNext()

@JakeGinnivan
Copy link

https://gist.github.com/HEskandari/7192698#file-mockingasynctask-cs-L12

mock.DoSomething().ReceivedCalls(); is not right mock.DoSomething() returns a task, then you are calling .ReceivedCalls() on a task which is not a substitute.

mock.ReceivedCalls(); should return one thing, which is mock.DoSomething()

@shiftkey
Copy link

shiftkey commented Jan 3, 2014

mock.Received().DoSomething(); is what you should be using to assert that a specific method was called

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