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?