C# 如何对心跳模式进行单元测试?
我正在编写一个客户端,它每秒向服务器发送一个“心跳信号”。客户端在后台线程中调用WCF服务以报告其活动 如何对此进行单元测试?我是否需要等待几秒钟,然后检查是否多次调用了适当的方法 它应该是某种场景测试吗?也许我不应该担心在整个客户生命周期中不断地呼叫服务 我可以测试对WCF服务的单个调用,但它不测试“心跳模式” 我使用的是TDD方法。(C#,努尼特,莫阿) 有什么建议或例子吗 编辑: 我觉得还不够清楚 这是我所拥有的更简单的版本:C# 如何对心跳模式进行单元测试?,c#,.net,unit-testing,nunit,C#,.net,Unit Testing,Nunit,我正在编写一个客户端,它每秒向服务器发送一个“心跳信号”。客户端在后台线程中调用WCF服务以报告其活动 如何对此进行单元测试?我是否需要等待几秒钟,然后检查是否多次调用了适当的方法 它应该是某种场景测试吗?也许我不应该担心在整个客户生命周期中不断地呼叫服务 我可以测试对WCF服务的单个调用,但它不测试“心跳模式” 我使用的是TDD方法。(C#,努尼特,莫阿) 有什么建议或例子吗 编辑: 我觉得还不够清楚 这是我所拥有的更简单的版本: public class FeedService { p
public class FeedService
{
private Timer t;
public FeedService()
{
t.Interval = 1000;
t.Elapsed += TimerElapsed;
t.Start();
}
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
t.Stop();
SendHeartbeat();
t.Start();
}
}
…这是我的测试:
[Test]
public void Heartbeat_called_twice_after_2_seconds()
{
var mockFeedService = new Mock<FeedService>();
Thread.Sleep(2000);
mockFeedService.Verify(x => x.SendHeartBeat(), Times.AtLeast(2));
}
[测试]
公共无效心跳\u在\u 2秒后调用\u两次()
{
var mockFeedService=new Mock();
《睡眠》(2000年);
验证(x=>x.SendHeartBeat(),Times.atly(2));
}
我有两个问题:1) 为什么我的考试总是不及格?我做错了什么?
2) 我应该测试它吗?您希望测试的功能必须首先隔离。例如,在本例中,有两个方面可以测试。一个是hearbeat组件实际上按照指定的时间表发送心跳消息。另一个是服务接收消息。如果您抽象了服务,那么您可以独立于服务实现来测试hearbeat组件。这可以在单元测试中完成,方法是启动hearbeat组件,然后休眠,然后验证存根或模拟服务实现是否收到了预期数量的消息。确保服务接收消息的测试是一个测试,因此不是“纯”单元测试。但是,由于无论如何都必须对其进行测试,因此您也可以为此编写一个测试用例。我将把与服务的交互封装在一个“网关”类型的类中。在您的测试中,这可以由一个mock代替,mock可以计算您进行的调用,或者您可能需要的任何统计数据 问候,,
Morten严格来说,您要测试的场景是一个集成测试 对于类似的测试构建场景,我采用的方法是使用这个方便的函数:
/// <summary>
/// Wait no longer than @waitNoLongerThanMillis for @thatWhatWeAreWaitingFor to return true.
/// Tests every second for the
/// </summary>
/// <param name="thatWhatWeAreWaitingFor">Function that when evaluated returns true if the state we are waiting for has been reached.</param>
/// <param name="waitNoLongerThanMillis">Max time to wait in milliseconds</param>
/// <param name="checkEveryMillis">How often to check for @thatWhatWeAreWaitingFor</param>
/// <returns></returns>
private bool WaitFor(Func<bool> thatWhatWeAreWaitingFor, int checkEveryMillis, int waitNoLongerThanMillis)
{
var waitedFor = 0;
while (waitedFor < waitNoLongerThanMillis)
{
if (thatWhatWeAreWaitingFor()) return true;
Console.WriteLine("Waiting another {0}ms for a situation to occur. Giving up in {1}ms ...", checkEveryMillis, (waitNoLongerThanMillis - waitedFor));
Thread.Sleep(checkEveryMillis);
waitedFor += checkEveryMillis;
}
return false;
}
它使用的c#功能仅在.Net4之后才可用,但这可能适合大多数.Net开发人员;这个解决方案是部分重构(包装)、部分测试、部分模拟,但您可能会发现,选择一个更容易测试的解决方案,也将被证明是一个更强的设计。非常感谢。我真的不在乎WCF服务是否接收到消息。我需要测试的是我的客户端每秒发送消息而不接收任何错误的能力。我使用模拟服务测试了一个对WCF服务的“手动”调用,但这并不是我想要实现的。方法“SendHeartbeat”应该是私有的,并且应该在重试时调用。
// WaitFor (transaction to become failed, checkEverySoOften, waitNoLongerThan)
int wait = (Settings.EventHandlerCoordinatorNoActivitySleepTime + 5) * 1000;
var failedEventExists = WaitFor(() => EventQueueManager.GetFailedEvents(0, 10).TotalRecords > 0, checkEveryMillis: 1000, waitNoLongerThanMillis: wait);
if (!failedEventExists)
Assert.Fail("Waited longer than " + wait + " without any evidence of the event having been handled. Expected to failed event on the queue.");