【问题标题】:Have mocked method output different out param each call with MOQ每次使用最小起订量调用模拟方法输出不同的输出参数
【发布时间】:2016-02-10 17:32:08
【问题描述】:

MOQ 有没有办法让方法上的顺序调用返回不同的out 参数? 获取方法的简单示例:

public void OutputANumber(out int number)

输出 1,然后输出 2(忽略它可以返回 int 的事实,这只是一个示例,不是真实代码)。

int number = 1;
mock.Setup(n => n.OutputANumber(out number));
number = 2;
mock.Setup(n => n.OutputANumber(out number));

由于第二个设置会覆盖第一个设置,因此不起作用,同样,SetupSequence 仅允许顺序返回。

【问题讨论】:

    标签: c# unit-testing testing moq out


    【解决方案1】:

    一种解决方案是使用回调将模拟传递给运行新设置的方法,就像这样

    int number = 1;
    mock.Setup(n => n.OutputANumber(out number)).Callback(() => ChangeOut(mock));
    
    void ChangeOut(Mock<type> mock)
    {
        int number = 2;
        mock.Setup(n => n.OutputANumber(out number));
    }
    

    或者您可以创建一个虚拟对象来跟踪调用次数并根据需要输出一个新值。

    【讨论】:

      【解决方案2】:

      如果您只需要两次连续调用,LukeW 的解决方案就可以解决。但如果序列较长,它可能会变得过于复杂。您可以使用Typemock Isolator 更轻松地解决它。看看下面的例子:

      public class ClassUnderTest
      {
          public void OutputANumber(out int number)
          {
              number = 3;
          }
      }
      
      [TestMethod, Isolated]
      public void TestOutSequence()
      {
          //Arrange
          var n = new ClassUnderTest();
      
          int number = 1;
          Isolate.WhenCalled(() => n.OutputANumber(out number)).IgnoreCall();
          number = 2;
          Isolate.WhenCalled(() => n.OutputANumber(out number)).IgnoreCall();
          Isolate.WhenCalled(() => n.OutputANumber(out number)).CallOriginal();
      
          //Act
          var res1 = 0;
          var res2 = 0;
          var resOriginal = 0;
          var resDefault = 0;
          n.OutputANumber(out res1);
          n.OutputANumber(out res2);
          n.OutputANumber(out resOriginal);
          n.OutputANumber(out resDefault);
      
          //Assert
          Assert.AreEqual(1, res1);
          Assert.AreEqual(2, res2);
          Assert.AreEqual(3, resOriginal);
          Assert.AreEqual(3, resDefault);
      }
      

      无需创建虚拟对象或其他方法。通过串行定义输出参数并使用 Isolate.WhenCalled(),您可以设置任何输出参数序列:

      int number = 1;
      Isolate.WhenCalled(() => n.OutputANumber(out number)).IgnoreCall();
      

      对 Isolate.WhenCalled() 的最后一次调用定义了从那一刻起该方法的默认行为。因此,在示例中,我返回了在假调用后调用的原始实现:

      Isolate.WhenCalled(() => n.OutputANumber(out number)).CallOriginal();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-19
        • 1970-01-01
        • 2020-09-21
        • 2011-11-17
        • 2020-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多