Метод возврата задачи Stubbing в асинхронном модульном тесте
Позволять'скажем, у меня есть следующий класс и интерфейс, от которого это зависит:
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();
}
Когда я тестирую этот метод, я могу сделать следующее (используя xUnit и Rhino Mocks):
[Fact]
public async Task MyTest()
{
IRepository repositoryStub = MockRepository.GenerateStub();
MyController controller = new MyController(repositoryStub);
await controller.MethodUnderTest(1);
}
Это не сSystem.NullReferenceException: ссылка на объект не установлена на экземпляр объекта.
Со следующей StackTrace:
UnitTest.MyController.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
Правильно ли, что эта ошибка возникает из-заCommit()
возвращаетсяnull
и машина состояний, сгенерированная для асинхронных / ожидающих вызововMoveNext()
на ?null
Я могу это исправить, сделав что-то вроде:
repositoryStub.Expect(r => r.Commit()).Return(Task.FromResult(true);
Но это немного странно .. Я могу использовать любойT
заFromResult
и тест запустится. Я могу'не найтиFromResult
метод, который будет возвращать неуниверсальный.Task
Имеет ли значение то, что я использую дляT
? Или я должен исправить это другим способом?