I'm trying to test the following:
protected IHealthStatus VerifyMessage(ISubscriber destination)
{
var status = new HeartBeatStatus();
var task = new Task<CheckResult>(() =>
{
Console.WriteLine("VerifyMessage(Start): {0} - {1}", DateTime.Now, WarningTimeout);
Thread.Sleep(WarningTimeout - 500);
Console.WriteLine("VerifyMessage(Success): {0}", DateTime.Now);
if (CheckMessages(destination))
{
return CheckResult.Success;
}
Console.WriteLine("VerifyMessage(Pre-Warning): {0} - {1}", DateTime.Now, ErrorTimeout);
Thread.Sleep(ErrorTimeout - 500);
Console.WriteLine("VerifyMessage(Warning): {0}", DateTime.Now);
if (CheckMessages(destination))
{
return CheckResult.Warning;
}
return CheckResult.Error;
});
task.Start();
task.Wait();
status.Status = task.Result;
return status;
}
with the following unit test:
public void HeartBeat_Should_ReturnWarning_When_MockReturnsWarning()
{
// Arrange
var heartbeat = new SocketToSocketHeartbeat(_sourceSubscriber.Object, _destinationSubscriber.Object);
heartbeat.SetTaskConfiguration(this.ConfigurationHB1ToHB2_ValidConfiguration());
// Simulate the message being delayed to destination subscriber.
_destinationSubscriber.Setup(foo => foo.ReceivedMessages).Returns(DelayDelivery(3000, Message_HB1ToHB2()));
// Act
var healthStatus = heartbeat.Execute();
// Assert
Assert.AreEqual(CheckResult.Warning, healthStatus.Status);
}
Message_HB1ToHB2() just returns a string of characters and the "Delay Delivery" method is
private List<NcsMessage> DelayDelivery(int delay, string message)
{
var sent = DateTime.Now;
var msg = new NcsMessage()
{
SourceSubscriber = "HB1",
DestinationSubscriber = "HB2",
SentOrReceived = sent,
Message = message
};
var messages = new List<NcsMessage>();
messages.Add(msg);
Console.WriteLine("DelayDelivery: {0}", DateTime.Now);
Thread.Sleep(delay);
Console.WriteLine("DelayDelivery: {0}", DateTime.Now);
return messages;
}
I'm using Moq as the mocking framework and MSTest as the testing framework. Whenever I run the unit test, I get the following output:
DelayDelivery: 04/04/2013 15:50:33
DelayDelivery: 04/04/2013 15:50:36
VerifyMessage(Start): 04/04/2013 15:50:36 - 3000
VerifyMessage(Success): 04/04/2013 15:50:38
Beyond the obvious "code smell" using the Thread.Sleep in the methods above, the result of the unit test is not what I'm trying to accomplish.
Can anyone suggest a better/accurate way to use the Moq framework to simulate a delay in "delivery" of the message. I've left out some of the "glue" code and only included the relevant parts. Let me know if something I've left out that prevents you from being able to understand the question.
I could not get Moq version to work, so I ended up making something like this:
a small example using WaitHandle:
When you setup your mock you can tell the thread to sleep in the return func:
I like and voted for serup's solution. My answer is a version of his converted for use as a library.
If you want a Moq mock to just sit and do nothing for a while you can use a callback:
I've tried that in LinqPad and if you adjust the
Thread.Sleep()
the execution time varies accordingly.I had a similiar situation, but with an Async method. What worked for me was to do the following: