【问题标题】:How can I assert that a particular method was called using NUnit?如何断言使用 NUnit 调用了特定方法?
【发布时间】:2014-12-17 23:39:27
【问题描述】:

作为测试的结果,我如何测试是否使用正确的参数调用了特定方法?我正在使用NUnit

该方法不返回任何内容。它只是写在一个文件上。我正在为System.IO.File 使用模拟对象。所以我想测试该函数是否被调用。

【问题讨论】:

    标签: c# tdd nunit moq


    【解决方案1】:

    需要更多上下文。所以我会放一个在这里添加最小起订量:

    pubilc class Calc {
        public int DoubleIt(string a) {
            return ToInt(a)*2;
        }
    
        public virtual int ToInt(string s) {
            return int.Parse(s);
        }
    }
    
    // The test:
    var mock = new Mock<Calc>();
    string parameterPassed = null;
    mock.Setup(c => x.ToInt(It.Is.Any<int>())).Returns(3).Callback(s => parameterPassed = s);
    
    mock.Object.DoubleIt("3");
    Assert.AreEqual("3", parameterPassed);
    

    【讨论】:

    • 当 Calc 不是抽象或接口时,这是否有效?据我所知Moq 制作动态代理以使其模拟不会生成新的 IL 指令,以使这成为可能...
    【解决方案2】:

    您必须使用一些模拟框架,例如TypemockRhino Mocks,或NMocks2

    NUnit 也有一个Nunit.Mock,但并不为人所知。

    起订量的语法可以找到here:

    var mock = new Mock<ILoveThisFramework>();
    
    // WOW! No record/reply weirdness?! :)
    mock.Setup(framework => framework.DownloadExists("2.0.0.0"))
        .Returns(true)
        .AtMostOnce();
    
    // Hand mock.Object as a collaborator and exercise it, 
    // like calling methods on it...
    ILoveThisFramework lovable = mock.Object;
    bool download = lovable.DownloadExists("2.0.0.0");
    
    // Verify that the given method was indeed called with the expected value
    mock.Verify(framework => framework.DownloadExists("2.0.0.0"));
    

    另外,请注意,您只能模拟 interface,因此如果您来自 System.IO.File 的对象没有接口,那么您可能无法做到。您必须将对 System.IO.File 的调用封装在您自己的自定义类中才能完成这项工作。

    【讨论】:

    • NUnit 只是运行测试,它不做模拟或验证。不同的职责。尽管我没有使用 Moq,但您应该能够验证对模拟对象的期望。
    • 是的,我看错地方了……我在看 nunit。现在我在看起订量。 :)
    • MOQ 也可以让你模拟抽象类。
    【解决方案3】:

    通过对接口使用模拟。

    假设您的类 ImplClass 使用接口 Finder,并且您希望确保使用参数“hello”调用 Search 函数;

    所以我们有:

    public interface Finder 
    {
      public string Search(string arg);
    }
    

    public class ImplClass
    {
      public ImplClass(Finder finder)
      {
        ...
      }
      public void doStuff();
    }
    

    然后你就可以为你的测试代码写一个mock了

    private class FinderMock : Finder
    {
      public int numTimesCalled = 0;
      string expected;
      public FinderMock(string expected)
      {
        this.expected = expected;
      }
      public string Search(string arg)
      {
        numTimesCalled++;
        Assert.AreEqual(expected, arg);
      }
    }
    

    然后是测试代码:

    FinderMock mock = new FinderMock("hello");
    ImplClass impl = new ImplClass(mock);
    impl.doStuff();
    Assert.AreEqual(1, mock.numTimesCalled);
    

    【讨论】:

      【解决方案4】:

      在 Rhino Mocks 中,有一个名为 AssertWasCalled 的方法

      这是一种使用方法

      var mailDeliveryManager = MockRepository.GenerateMock<IMailDeliveryManager>();
      
      var mailHandler = new PlannedSending.Business.Handlers.MailHandler(mailDeliveryManager);
      
      mailHandler.NotifyPrinting(User, Info);
      
      mailDeliveryManager.AssertWasCalled(x => x.SendMailMessage(null, null, null), o => o.IgnoreArguments());

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多