N 抛出参数以外的异常的替代条件

NSubstitute conditions for throwing exception other than parameters

我正在使用 NSubstitute 模拟我的测试方法使用的 class。这个模拟 class 可能会在某些情况下抛出特定异常。

我正在测试的方法有一些 "retry" 逻辑,它在捕获此异常时执行。我正在尝试测试此重试逻辑。所以,我需要这个模拟 class 的一个特定方法来有时抛出异常,但其他时候不会。不幸的是,抛出这个异常的方法没有参数,所以我不能根据参数来抛出逻辑。

如何让模拟对象的方法抛出异常:

A) ...前 N 次被调用

B) ...基于参数在它之前调用的一些其他方法

C) ...除了传入的参数之外的任何其他条件下

为了让您更清楚地了解我正在尝试做的事情,我的代码类似于:

IDataSender myDataSender = GetDataSender();
int ID = GetNextAvailableID();
myDataSender.ClearData();
myDataSender.Add(ID,"DataToSend");
bool sendSuccess = false;
while (!sendSuccess)
{
   try
   {
      myDataSender.SendData();
      sendSuccess = true;
   }
   catch (IDCollisionException)
   {
      ID++;
      MyDataSender.ClearData();
      myDataSender.Add(ID,"DataToSend");
   }
}

所以,我需要测试我的重试逻辑,我需要模拟那个 IDCollisionException。但是,我不能让 SendData() 每次都抛出异常,否则重试循环永远不会成功。

我可以在这里做什么?

如果我对问题的理解正确,您可以使用 When..Do 并关闭局部变量来获得此行为。

const int throwUntil = 3;
var callsToSendData = 0;
var dataSender = Substitute.For<IDataSender>();

dataSender
    .When(x => x.SendData())
    .Do(x =>
    {
        callsToSendData++;
        if (callsToSendData < throwUntil)
        {
            throw new DbCollisionException();
        }
    });

同样,您也可以使用 callbacks 在本地捕获传递给其他方法的参数,并在 Do 块中访问它们(而不是仅仅使用计数器)。