简体   繁体   中英

How to fake an object in NSubstitute and ignore its method's internal implementation?

I'm new to NSubstitute and trying to fake an existing class named OrgDataWS . This class has a method named 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;
 }

The following is my test methods:

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

However, when I run my test methods, this line

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

threw an exception. This exception is from the implementation of OrgDataManager class, from my understanding, this is not supposed to happen. The purpose of using that clause is that I hope if the orgManagerStub 's DataDataSet method is invoked with any Int parameter, just return my xmlElement instance. I didn't hope my code to run the detailed implementation of OrgDataManager .

What's wrong with my test code? How to fix it?

As per the documentation :

Warning: Substituting for classes can have some nasty side-effects. For starters, NSubstitute can only work with virtual members of the class , so any non-virtual code in the class will actually execute! If you try to substitute for your class that formats your hard drive in the constructor or in a non-virtual property setter then you're asking for trouble. If possible, stick to substituting interfaces.

(my emphasis)

The declaration you showed is not virtual, so the solution is to either create an interface for it, and substitute for that, or at least make that method virtual (and possibly other methods as well).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM