Let's say I have the following class and an interface it depends on:
public class MyController { private IRepository _repository; public MyController(IRepository repository) { _repository = repository; } public async Task MethodUnderTest(int someId) { var o = await _repository.FindById(someId); // update o await _repository.Commit(); } } public interface IRepository { Task Commit(); }
When I unit test this method I can do the following (using xUnit and Rhino Mocks):
[Fact] public async Task MyTest() { IRepository repositoryStub = MockRepository.GenerateStub<IRepository>(); MyController controller = new MyController(repositoryStub); await controller.MethodUnderTest(1); }
This fails with a System.NullReferenceException : Object reference not set to an instance of an object.
With the following StackTrace:
UnitTest.MyController.<MethodUnderTest>d__0.MoveNext() in \UnitTest\Class1.cs:line 35 --- 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() at \UnitTest\Class1.cs:line 20
Is it correct that this error occurs because the Commit()
returns null
and the statemachine generated for the async/await calls MoveNext()
on a null
?
I can fix this by doing something like:
repositoryStub.Expect(r => r.Commit()).Return(Task.FromResult<bool>(true);
But this feels a little strange.. I can use any T
for FromResult<T>
and the test will run. I can't find a FromResult
method that will return a non-generic Task
.
Does it matter what I use for T
? Or should I fix this some other way?
You will need to return something; async Task
methods cannot ever return null
.
The T
doesn't matter. You could declare a static readonly Task SuccessTask = Task.FromResult<object>(null);
as a helper constant if you want. I have similar constants in my AsyncEx library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With