chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi,

I'm trying to write a test case where I need to mock XmlDocument and XmlNode. Code behind the method contains two foreach loops :
           foreach (XmlNode node in root.ChildNodes)
                {
                    if (string.Compare(node.Name, "token", true) != 0) continue;

                    string key = node.Attributes[0].Value;
                    string value = "";
                    bool add = false;
                    foreach (XmlNode currentNode in node.ChildNodes)
                    {
                        if (!string.Equals(currentNode.Name, "language", StringComparison.OrdinalIgnoreCase)) continue;

                        if (!string.Equals(cultureName, currentNode.Attributes[0].Value, StringComparison.OrdinalIgnoreCase)) continue;

                        value = currentNode.InnerText;
                        add = true;
                    }

                    if (add)
                    {
                        languageTable.Add(key, value);
                    }
                }


Can any body suggest how i can mock the XmlNode attribute or infact itself XmlNode.

Thanks
asked by mohit.vashishtha (1.2k points)

3 Answers

0 votes
Hi,

You can fake the XML document and children using similar code:
[TestMethod]
public void TestXMLAttributes()
{
    // Arrange
    var root = Isolate.Fake.Instance<XmlElement>();

    var elementOne = Isolate.Fake.Instance<XmlElement>();
    Isolate.WhenCalled(() => elementOne.Attributes[0].Value).WillReturn("Value1");
    
    var elementTwo = Isolate.Fake.Instance<XmlElement>();
    Isolate.WhenCalled(() => elementTwo.Attributes[0].Value).WillReturn("Value2");

    Isolate.WhenCalled(() => root.ChildNodes)
              .WillReturnCollectionValuesOf(new[] { elementOne, elementTwo });

    // Act
    var actualAttributes = new List<string>();
    foreach (XmlNode childNode in root.ChildNodes)
    {
        actualAttributes.Add(childNode.Attributes[0].Value);
    }

    // Assert
    CollectionAssert.AreEquivalent(new []{"Value1", "Value2"}, actualAttributes);
}


In this example we created an XML element, faked its children list and set child attributes behavior to return specific values.

I am not sure what exactly are you trying to test in your code. Since XML is easy to create data object, it may be easier to use real XML document instead of fake. It will also make the test more readable and less fragile. If you're not verifying anything against the XML there is no must to fake it.

Regards,
Elisha
Typemock Support
answered by Elisha (12k points)
0 votes
Thanks for reply...

Actualy i am still stuggling with same issue. When i tried to create the mock object named as "root" from the XmlDocument then it is throwing object reference error. Befor the foeeach loop there is lines of code as:
 Hashtable languageTable = new Hashtable();
            string cultureName = currentInfo.Name;
            XmlDocument doc = new XmlDocument();
            XmlTextReader myReader = new XmlTextReader(xmlUrl);
              myReader.XmlResolver = myResolver;
                doc.Load(myReader);
                XmlNode root = doc.ChildNodes[1];
            foreach (XmlNode node in root.ChildNodes)   \Here it breaks 
                {
                    if (string.Compare(node.Name, "token", true) != 0) continue;

I am able to mock the "XmlDocument" and its load call. But when its trying to fetch the first child node, it returns me null object.

Please share some inputs that how can i mock the first element of the XML document as XMLNode("root").

Thanks
Mohit
answered by mohit.vashishtha (1.2k points)
0 votes
Hi,

You can handle it using indexer faking:

Isolate.WhenCalled(() => doc.ChildNodes[1]).WillReturn(fakeElement);


Regards,
Elisha
Typemock Support
answered by Elisha (12k points)
...