how do you mock an xml for unit testing?

拟墨画扇 提交于 2019-12-21 12:31:11

问题


I need to unit testing this GetData method.

    public MessageResponse GetData(XmlElement requestElement)
    {   
        MessageResponse MsgResponse = new MessageResponse();


        if (requestElement.Attributes["employeeNo"] == null){
            MsgResponse.Messages = new List<string>();
            MsgResponse.Messages.Add("Attribute employeeNo is missing");
            MsgResponse.Error = true;
            return MsgResponse;
        }
        if (requestElement.Attributes["xmlEmployeeName"] == null){
            MsgResponse.Messages.Add("Attribute xmlEmployeeName is missing");
            MsgResponse.Error = true;
            return MsgResponse;
        }
        return MsgResponse;
    }

this method needs a XmlElement parameter. how do I mock it? in my code, I first created a xmlDocument, then load the xml file.

            XmlDocument doc = new XmlDocument();
            doc.Load(xmlFilePath);
            requestElement = doc.DocumentElement;

for me to test it, first i need to create a xml file without employeeNo, the create antoher one without name, maybe alot more for other scenarios. it just seems like alot work. is there a better way to test it?

should I use moq or other testing framework to simplify the testing?


回答1:


You can just create the element you want to test with, w/o reading a file at all:

var doc = new XmlDocument();
doc.LoadXml("<MyTestElement/>");
var myTestElement = doc.DocumentElement;
myTestElement.Attributes["employeeNo"] = "fakeId";

var response = myTestResponder.GetData(myTestElement);

//assert whatever you need to

NOTE: every time you find out that the test is too hard to write, usually this means that your class/method does too much.

I would assume, that your method verifies the input, than does something with the data provided. I would suggest that you abstract the data reading part (using some xml deserializer) to populate the data model you need for your application.

Then run validation on the result of the deserialized data. Something like:

public MessageResponse GetData(XmlElement requestElement)
{
   var data = _xmlDeserializer.Deserialize(requestElement);
   var validationResult = _validator.Validate(data);
    if (validationResult.Errors.Count > 0)
    {
         //populate errors
        return result;
    }

    _dataProcessor.DoSomethingWithData(data);
}

Take a look at FluentValidation for a nice validation library.

If you go the above route, then your tests will be much simpler.




回答2:


[TestMethod]
public void GetData_Returns_Correct_Message_When_EmployeeNo_Is_Null()
{
    var inputWithoutEmployeeNo = GetElement(@"<input></input>");

    var actual = GetData(inputWithoutEmployeeNo);

    Assert.IsTrue(actual.Error, "Error should be true when employee no. is missing");
    Assert.IsNotNull(actual.Messages);
    Assert.AreEqual(1, actual.Messages.Count);
    Assert.AreEqual("Attribute employeeNo is missing", actual.Messages[0]);
}

private XmlElement GetElement(string xml)
{
    var doc = new XmlDocument();
    doc.LoadXml(xml);
    return doc.DocumentElement;
}

While working on the unit test, I found out that the code throws a NullReferenceException. The following unit test demonstrates the issue:

[TestMethod]
[ExpectedException(typeof(NullReferenceException))]
public void GetData_Throws_NullReferenceException_When_EmployeeNo_Is_Not_Null_And_XmlEmployeeName_Is_Null()
{
    var inputWithoutEmployeeNo = GetElement(@"<input employeeNo='123'></input>");

    GetData(inputWithoutEmployeeNo);
}


来源:https://stackoverflow.com/questions/19733088/how-do-you-mock-an-xml-for-unit-testing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!