mardi 12 avril 2016

Async callback on mocked object not awaiting

I am attempting to mock a complicated situation for unit testing:

_mockController = new Mock<IController>();
_mockController.Setup(tc => tc.Interrupt(It.IsAny<Func<Task>>()))
    .Callback<Func<Task>>(async f => await f.Invoke());

Where IController has a method Interrupt(Func<Task>> f).

My objects under test do call Interrupt(), and I can verify the call like so:

_mockController.Verify(tc => tc.Interrupt(It.IsAny<Func<Task>>()), Times.Once);

...but when the argument Func<Task> is invoked in the callback, the await keyword is not respected in the Task: the execution of the test continues before the Task finishes (despite the await in the callback). One symptom of this is that adding an await Task.Delay(1000) in the Interrupt() Task argument turns a passing test into a failing test.

Is this behavior due to a nuance of how threads or Tasks are handled during test? Or a limitation of Moq? My test methods have this signature:

[Test]
public async Task Test_Name()
{ ... }

Aucun commentaire:

Enregistrer un commentaire