Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何对心跳模式进行单元测试?_C#_.net_Unit Testing_Nunit - Fatal编程技术网

C# 如何对心跳模式进行单元测试?

C# 如何对心跳模式进行单元测试?,c#,.net,unit-testing,nunit,C#,.net,Unit Testing,Nunit,我正在编写一个客户端,它每秒向服务器发送一个“心跳信号”。客户端在后台线程中调用WCF服务以报告其活动 如何对此进行单元测试?我是否需要等待几秒钟,然后检查是否多次调用了适当的方法 它应该是某种场景测试吗?也许我不应该担心在整个客户生命周期中不断地呼叫服务 我可以测试对WCF服务的单个调用,但它不测试“心跳模式” 我使用的是TDD方法。(C#,努尼特,莫阿) 有什么建议或例子吗 编辑: 我觉得还不够清楚 这是我所拥有的更简单的版本: public class FeedService { p

我正在编写一个客户端,它每秒向服务器发送一个“心跳信号”。客户端在后台线程中调用WCF服务以报告其活动

如何对此进行单元测试?我是否需要等待几秒钟,然后检查是否多次调用了适当的方法

它应该是某种场景测试吗?也许我不应该担心在整个客户生命周期中不断地呼叫服务

我可以测试对WCF服务的单个调用,但它不测试“心跳模式”

我使用的是TDD方法。(C#,努尼特,莫阿)

有什么建议或例子吗

编辑:

我觉得还不够清楚

这是我所拥有的更简单的版本:

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.");