I have some production code which runs asynchronously (actually an actor system). The following test checks whether some interface is properly called if a certain event occurs. It currently reads:
var restarts = new Mock<ISystemCommandService>();
restarts.Setup(c => c.CommandType()).Returns("RestartCommand");
var subject = CreateSubject(restarts.Object);
subject.Tell(new Event ("TestEventName", "ValueChanged"));
Thread.Sleep(millisecondsTimeout: 300);
restarts.Verify(r => r.CommandAsync(It.Is<string>(s =>
s.Contains(@"""RestartBackend"":true"))));
The test is green and all is well, but I'm unhappy about the Thread.Sleep(300) part. I can't remove it because the actor system needs some time to process the message, but the 300 ms are hardware dependant. It would be great if I could delete the Sleep() and write
restarts.Verify(r => r.CommandAsync((It.Is<string>(s =>
s.Contains(@"""RestartBackend"":true"))),
TimeSpan.FromMilliseconds(500));
and Verify would wait up to 500 ms before it fails. Or is there another way?
CodePudding user response:
Ok, the answer is https://github.com/sekskant/AsyncVerifyForMoq. This contains an extension method for Mock, which provides an async verify with timeout. I removed the Sleep() and the last line now reads:
await restarts.AsyncVerify(r => r.CommandAsync(It.Is<string>(s =>
s.Contains(@"""RestartBackend"":true"))),
Times.Once(),
TimeSpan.FromSeconds(3));
It's actually 100 ms slower than using Sleep() on my development machine, but I don't care, this won't fail even on the slowest hardware. Thanks!