Stubbing-Task-Rückgabemethode im asynchronen Komponententest

Nehmen wir an, ich habe die folgende Klasse und ein Interface, von dem es abhängt:

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();
}

Wenn ich diese Methode teste, kann ich Folgendes tun (mit xUnit und Rhino Mocks):

[Fact]
public async Task MyTest()
{
    IRepository repositoryStub = MockRepository.GenerateStub<IRepository>();

    MyController controller = new MyController(repositoryStub);

    await controller.MethodUnderTest(1);
}

Dies scheitert mit einemSystem.NullReferenceException: Der Objektverweis wurde nicht auf eine Instanz eines Objekts festgelegt.

Mit folgendem 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

Ist es richtig, dass dieser Fehler auftritt, weil dieCommit() kehrt zurücknull und die Statemachine, die für die Async / Warten-Aufrufe generiert wurdeMoveNext() auf einennull?

Ich kann das beheben, indem ich etwas mache wie:

repositoryStub.Expect(r => r.Commit()).Return(Task.FromResult<bool>(true);

Aber das fühlt sich ein bisschen seltsam an. Ich kann jeden benutzenT zumFromResult<T> und der Test wird ausgeführt. Ich kann keine findenFromResult Methode, die eine nicht generische zurückgibtTask.

Ist es wichtig, wofür ich benutze?T? Oder sollte ich das auf andere Weise beheben?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage