Rhino模拟断言任何调用都匹配预期的参数

时间:2011-08-06 09:58:34

标签: unit-testing mocking rhino-mocks

我想测试以下代码:

foreach (CallQueueData queueData in _configurationProvider.CallQueues.Values)
 {
    _chimeManager.AddConfig(new ChimeConfigData(
       ChimeKey.Create(ChimeType.CallQueue, queueData.Name));

    if (queueData.LowChime != null)
    {
       _chimeManager.AddConfig(new ChimeConfigData(
          ChimeKey.Create(ChimeType.QueueLowChime, queueData.Name));
    }

    if (queueData.HighChime != null)
    {
       _chimeManager.AddConfig(new ChimeConfigData(
          ChimeKey.Create(ChimeType.QueueHighChime, queueData.Name));
    }
 }

我的一个测试看起来像这样:

public void ShouldAddHighChimeConfigToChimeManager_IfServiceIsStarted_AndHighChimeIsConfigured()
  {
     // GIVEN
     InitializeObjectUnderTestWithougStartingService();

     var callQueueData = new CallQueueData
     {
        Name = "Emergency",
        HighChime = new ChimeType(1, "High")
     };

     CallQueues.Add(callQueueData.Id, callQueueData);

     // WHEN
     _mgr.Startup();

     // THEN
     ChimeManager.AssertWasCalled(x => x.AddConfig(Arg<ChimeConfigData>.Matches(
        y => y.Key == ChimeKey.Create(ChimeType.HighChime, callQueueData.Name))));
  }

这里的问题是ChimeManager的AddConfig方法被多次调用 而且我不想指定在它与我的方法匹配之前必须调用的频率。

// i dont like this repeat twice because this ties the test code to much to the production code
ChimeManager.AssertWasCalled(x => x.AddConfig(Arg<ChimeConfigData>.Matches(
        y => y.Key == ChimeKey.Create(ChimeType.HighChime, callQueueData.Name)),
        y => y.Repeat.Twice));

我更愿意说:

ChimeManager.AssertWasCalled(x => x.AddConfig(Arg<ChimeConfigData>.Matches(
        y => y.Key == ChimeKey.Create(ChimeType.HighChime, callQueueData.Name)),
        y => y.Repeat.Any / y.Match.Any));

Unfortunatley Repeat.Any在这种情况下无效,任何没有Match.Any。

我如何断言使用指定的参数调用此方法,但调用它的频率并不重要。当对方法的一个调用与指定的参数匹配时,断言不会失败。

1 个答案:

答案 0 :(得分:2)

编写测试以验证方法的结果,而不是编写测试来验证方法的实现(随着时间的推移变得脆弱)。在这种情况下,您似乎希望确保正确填充_chimeManager。

如果您编写的测试只是发送一些数据然后验证结果,那么您的单元测试将不太可能随着时间的推移而中断。假设在将来的某个时刻,_chimeManager的数量通过数据库调用或除了Add方法之外的其他一些方法发生?如果针对实现编写测试,则测试将中断。但是,如果您编写测试以确保在给定某个输入的情况下_chimeManager已正确填充,那么您将获得一个不会因“如何”更改而中断的测试。