This is a migrated thread and some comments may be shown as answers.

Can't mock XmlDocument.SelectNodes

2 Answers 223 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Neil
Top achievements
Rank 1
Neil asked on 06 Sep 2012, 08:13 PM
[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 Answers, 1 is accepted

Sort by
0
Neil
Top achievements
Rank 1
answered on 06 Sep 2012, 11:22 PM
I think I know why.... I have to do MsCorlib mocking for this
0
Ricky
Telerik team
answered on 12 Sep 2012, 03:13 PM
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.

Tags
General Discussions
Asked by
Neil
Top achievements
Rank 1
Answers by
Neil
Top achievements
Rank 1
Ricky
Telerik team
Share this question
or