unit-testingmoqmstestmoq-3

how do you mock an xml for unit testing?


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?


Solution

  • 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.