Can't mock XmlDocument.SelectNodes

3 posts, 0 answers
  1. Neil
    Neil avatar
    2 posts
    Member since:
    Jan 2012

    Posted 06 Sep 2012 Link to this post

    [TestMethod]
    public void MyTestMethod()
    {   
    // here when I look at nodes, it has values
    XmlNodeList nodes = GetPresetNodes();
    XmlDocument mockedXmlDocument = Mock.Create<XmlDocument>();

    Mock.Arrange(() => mockedXmlDocument.Load("C:\\Presets.xml"))
    .IgnoreInstance()
    .DoNothing();
     
    // it doesn't matter if I have IgnoreArguments here or not
    Mock.Arrange(() => mockedXmlDocument.SelectNodes("//presets/preset"))
    .IgnoreArguments()
            .IgnoreInstance()
    .Returns(presetNodes);

    ClassA c = new ClassA();

    }

    public class ClassA
    {
    public static readonly ClassToTest = new ClassToTest();
    ....
    }

    public sealed class ClassToTest
    {
    // constructor
    public ClassToTest()
    {
    XmlDocument doc = new XmlDocument();

    // this correctly gets ignored
    doc.Load("
    C:\\Presets.xml");

    // this returns an empty XmlNodeList and not the one I created in the test
    XmlNodeList presets = doc.SelectNodes("//presets/preset");
    }
    }

    Any Ideas?


  2. Neil
    Neil avatar
    2 posts
    Member since:
    Jan 2012

    Posted 06 Sep 2012 Link to this post

    I think I know why.... I have to do MsCorlib mocking for this
  3. DevCraft R3 2016 release webinar banner
  4. Ricky
    Admin
    Ricky avatar
    467 posts

    Posted 12 Sep 2012 Link to this post

    Hi Neil,
    Thanks again for contacting us. Here in the following line if SelectNodes is already executed then you wont be able to mock it later in the test.

    // here when I look at nodes, it has values
    XmlNodeList nodes = GetPresetNodes();

    The solution is to initialize the target members. Here is the full working test that should give the idea:

    [TestClass]
       public class UnitTest1
       {
           static UnitTest1()
           {
               Mock.Partial<XmlDocument>().For<XmlDocument, string>((x, i) => x.Load(i));
               Mock.Partial<XmlDocument>().For<XmlDocument, string>((x, i) => x.SelectNodes(i));
           }
            
     
           [TestMethod]
           public void MyTestMethod()
           {
               // here when I look at nodes, it has values
               XmlNodeList nodes = GetPresentNodes();
               XmlDocument mockedXmlDocument = Mock.Create<XmlDocument>();
     
               Mock.Arrange(() => mockedXmlDocument.Load("C:\\Presets.xml"))
                   .IgnoreInstance()
                   .DoNothing();
     
               // it doesn't matter if I have IgnoreArguments here or not
               Mock.Arrange(() => mockedXmlDocument.SelectNodes("//b"))
                   .IgnoreArguments()
                       .IgnoreInstance()
                   .Returns(nodes);
     
               SomeClass someClass = new SomeClass();
     
               Assert.IsTrue(someClass.GetNodes().Count == 3);
           }
     
     
           public class SomeClass
           {
               public XmlNodeList GetNodes()
               {
                   XmlDocument doc = new XmlDocument();
     
                   doc.Load("aaa");
     
                   return doc.SelectNodes("//b");
               }
           }
     
           private XmlNodeList GetPresentNodes()
           {
               XmlDocument xmldoc = new XmlDocument();
               xmldoc.LoadXml("<a><b /><b /><b /></a>");
               return xmldoc.SelectNodes("//b");
           }
       }


    In addition, here goes the link to a post in JustMock online document that gives more details on Mock.Initialize
    http://www.telerik.com/help/justmock/basic-usage-mock-initialize.html 

     
    Kind Regards,
    Ricky
    the Telerik team

    Time to cast your vote for Telerik! Tell DevPro Connections and Windows IT Pro why Telerik is your choice. Telerik is nominated in a total of 25 categories.

Back to Top