如何伪造NSubstitute中的对象并忽略其方法的内部实现?

时间:2014-08-25 07:07:08

标签: c# unit-testing nsubstitute

我是NSubstitute的新手并试图伪造一个名为OrgDataWS的现有类。该类有一个名为GetDataSet的方法:

 public XmlElement GetDataSet(int token)
 {
        string perfLogMessage = string.Format("Org.GetDataSet: {0}", Guid.NewGuid().ToString());
        MultiMessagePerformanceCounter performanceCounter = MultiMessagePerformanceCounter.StartNew(perfLogMessage);
        XmlElement result = orgDataManager.GetDataSet(token);
        performanceCounter.Stop();

        return result;
 }

以下是我的测试方法:

 [TestMethod]
 public void GetDataSetTest()
 {
      var dataWSStub = Substitute.For<OrgDataWS>();

      var orgManagerStub = Substitute.For<OrgDataManager>();

      var document = new XmlDocument();
      var xmlElement = document.CreateElement("a");
      orgManagerStub.GetDataSet(Arg.Any<int>()).Returns<XmlElement>(xmlElement);


      dataWSStub.OrgDataManager = orgManagerStub;


      var result = dataWSStub.GetDataSet(99);
 }

但是,当我运行我的测试方法时,这一行

orgManagerStub.GetDataSet(Arg.Any<int>()).Returns<XmlElement>(xmlElement);

抛出异常。这个例外来自OrgDataManager类的实现,根据我的理解,这不应该发生。使用该子句的目的是希望如果使用任何orgManagerStub参数调用DataDataSet的{​​{1}}方法,只需返回我的Int实例。我不希望我的代码运行xmlElement的详细实现。

我的测试代码出了什么问题?如何解决?

1 个答案:

答案 0 :(得分:13)

根据the documentation

  

警告:替换课程会产生一些令人讨厌的副作用。 首先,NSubstitute只能使用类的虚拟成员,因此类中的任何非虚拟代码都将实际执行!如果您尝试替换在构造函数或非虚拟属性设置器中格式化硬盘驱动器的类,那么您就会遇到麻烦。如果可能的话,坚持用接口代替。

(我的重点)

您展示的声明不是虚拟的,因此解决方案是为其创建一个接口,并替换它,或者至少使该方法成为虚拟(以及可能还有其他方法)。