Método de devolución de tareas de apéndice en una prueba de unidad asíncrona
Digamos que tengo la siguiente clase y una interfaz de la que depende:
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();
}
Cuando pruebo por unidad este método, puedo hacer lo siguiente (utilizando xUnit y Rhino Mocks):
[Fact]
public async Task MyTest()
{
IRepository repositoryStub = MockRepository.GenerateStub<IRepository>();
MyController controller = new MyController(repositoryStub);
await controller.MethodUnderTest(1);
}
Esto falla con unaSystem.NullReferenceException: referencia de objeto no establecida en una instancia de un objeto.
Con el siguiente 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
¿Es correcto que este error ocurra porque elCommit()
devolucionesnull
y el statemachine generado para las llamadas async / awaitMoveNext()
en unnull
?
Puedo arreglar esto haciendo algo como:
repositoryStub.Expect(r => r.Commit()).Return(Task.FromResult<bool>(true);
Pero esto se siente un poco extraño ... puedo usar cualquierT
paraFromResult<T>
y la prueba se ejecutará. No puedo encontrar unFromResult
Método que devolverá un no genérico.Task
.
¿Importa para qué uso?T
? ¿O debería arreglar esto de otra manera?