【问题标题】:Rhino mocks assert that any call matches expected argumentsRhino 模拟断言任何调用都匹配预期的参数
【发布时间】:2011-08-06 09:58:34
【问题描述】:

我想测试以下代码:

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

不幸的是,Repeat.Any 在这种情况下是无效的,any 没有 Match.Any。

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

【问题讨论】:

    标签: unit-testing mocking rhino-mocks


    【解决方案1】:

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

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

    【讨论】:

    • 好的,这意味着我应该在这种情况下使用“真正的”ChimeManager 而不是模拟的,然后断言 ChimeManagers 配置。嗯,因为它是一个注入的依赖项,我认为我应该模拟它,但我喜欢这种新方法。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多