简体   繁体   中英

How to test methods with XDocument.Load()

I have got following code:

void Foo(string path){
    try{
        XDocument document = XDocument.Load(path);
        Validate(document);
        //Some logic
    }
    catch(Exception ex){
        //Some logic
    }
}
void Validate(XDocument document){
     XmlSchemaSet schema = new XmlSchemaSet();
     schema.Add("", XmlReader.Create(new StringReader("XsdFile")));
     document.Validate(schema, null);
}

How to test this method? I would like to check three cases: - Correct XML - Incorrect XML - Not XML (for example .bmp file in path) I'm using Visual Studio tests.

You can deploy additional files when your test is run using the [DeploymentItem] attribute. They will be copied to TestContext.TestDeploymentDir .

// assume this XML file is in the root of the test project, 
// and "Copy to Output Directory" property of the file is set to "Copy always"
const string ValidXmlFileName = "valid.xml"; 

[TestMethod]
[DeploymentItem(ValidXmlFileName)]
public void Validate_ValidXml_ShouldBeOk() {

    string path = Path.Combine(TestContext.TestDeploymentDir, ValidXmlFileName);

    // perform test with the deployed file ...
}

Further reading: How to: Deploy Files for Tests

This code is tightly coupled to static implementation concerns, and given the title and question asked leads me to believe this is an XY problem .

Addressing the shortcomings of this code, it would need to be refactored to decouple it from implementation concerns.

The actual loading and validating of the document can be delegated out to their own concerns as demonstrated in the following example

public interface IDocumentLoader<T> where T : class {
    T Load(string path);
}

public interface IXDocumentLoader : IDocumentLoader<XDocument> { }
public class XDocumentLoader : IXDocumentLoader {
    public XDocument Load(string path) {
        return XDocument.Load(path);
    }
}

public interface IDocumentValidator<T> where T : class {
    void Validate(T document);
}

public interface IXDocumentValidator : IDocumentValidator<XDocument> { }
public class XDocumentValidator : IXDocumentValidator {
    public void Validate(XDocument document) {
        XmlSchemaSet schema = new XmlSchemaSet();
        schema.Add("", XmlReader.Create(new StringReader("XsdFile")));
        document.Validate(schema, null);
    }
}

public class Subject {
    private IXDocumentLoader loader;
    private IXDocumentValidator validator;

    public Subject(IXDocumentLoader loader, IXDocumentValidator validator) {
        this.loader = loader;
        this.validator = validator;
    }

    public void Foo(string path) {
        try {
            XDocument document = loader.Load(path);
            validator.Validate(document);
            //Some logic
        } catch (Exception ex) {
            //Some logic
        }
    }
}

The majority of the provided login in the original example has be delegate out. This would allow each aspect to be tested in isolation without side effects and even the need to load an actual XDocument from disk if so desired.

The given scenarios can be tested with only the necessary dependencies provided for that test. This can be used to test that exception is caught, or something else in the logic you omitted from the original question.

Using a SOLID approach when designing code allows it to be easier to maintain, which would include unit testing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM