wartet ich eine komplizierte Situation für Unit-Tests zu verspotten bin versucht:Async Rückruf bei verspottet Objekt nicht
_mockController = new Mock<IController>();
_mockController.Setup(tc => tc.Interrupt(It.IsAny<Func<Task>>()))
.Callback<Func<Task>>(async f => await f.Invoke());
Wo IController
einen Hohlraum Methode Interrupt(Func<Task>> f)
, das einig Arbeit Warteschlangen zu tun.
Meine Objekte im Test nennen Interrupt()
, und ich kann den Anruf wie so überprüfen:
_mockController.Verify(tc => tc.Interrupt(It.IsAny<Func<Task>>()), Times.Once);
... aber wenn das Argument Func<Task>
in der Callback aufgerufen wird, wird das await
Schlüsselwort nicht in dem angesehenen Task
: Die Ausführung des Tests wird fortgesetzt, bevor die Task
beendet wird (trotz await
im Rückruf). Ein Symptom dafür ist, dass das Hinzufügen eines await Task.Delay(1000)
im Interrupt()
Task
Argument einen bestandenen Test zu einem fehlgeschlagenen Test macht.
Liegt dieses Verhalten an einer Nuance davon, wie Threads oder Task
s während des Tests behandelt werden? Oder eine Einschränkung von Moq? Meine Testmethoden haben diese Unterschrift:
[Test]
public async Task Test_Name()
{
}
Ich vermute, es ist eine Beschränkung von Moq, aber Sie müssen ein Problem mit ihnen melden, um sicherzustellen, dass. –
Ich öffnete [diese Ausgabe] (https://github.com/moq/moq4/issues/256) mit Moq. Ich werde mit ihrer Antwort aktualisieren. – jdslepp
Meine Lösung besteht darin, eine Stubbed-Implementierung von IController zu schreiben, die im Grunde eine benutzerdefinierte Mock ist: Sie protokolliert Aufrufe und führt diese Interrupts asynchron in einer Methode aus, die 'Task' zurückgibt, was der Schlüssel ist. – jdslepp