Как проверить XML де- / сериализацию - PullRequest
1 голос
/ 04 августа 2020

Итак, я попытался создать очень простой XmlFileWriter

public class XmlFileWriter
{
    public void WriteTo<TSerializationData>(string path, TSerializationData data)
    {
        using (StreamWriter streamWriter = new StreamWriter(path))
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(TSerializationData));
            xmlSerializer.Serialize(streamWriter, data);
        }
    }
}

и XmlFileReader

public class XmlFileReader
{
    public TSerializationData ReadFrom<TSerializationData>(string path)
    {
        using (StreamReader streamReader = new StreamReader(path))
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(TSerializationData));

            return (TSerializationData) xmlSerializer.Deserialize(streamReader);
        }
    }
}

Я хочу создать модульные тесты для них обоих с xUnit . Поскольку они связаны с файловой системой, я искал способ как-то подделать ее. Многие сообщения настоятельно рекомендуют пакет System.IO.Abstractions и дополнительный TestingHelpers .

Я покажу только тесты для читателя, поскольку оба сценария ios очень похожи. Это то, что у меня есть до сих пор

[Fact]
public void ThrowsExceptionIfPathIsInvalid()
{
    XmlFileReader xmlFileReader = new XmlFileReader();

    // use an empty path since it should be invalid
    Assert.Throws<Exception>(() => xmlFileReader.ReadFrom<object>(string.Empty));
}

[Fact]
public void DeserializesDataFromXmlFile()
{
    // Generate dummy data with default values
    MyDummyClass dummyData = new MyDummyClass();
    XmlFileWriter xmlFileWriter = new XmlFileWriter();
    XmlFileReader xmlFileReader = new XmlFileReader();
    string filePath = "???"; // TODO

    // Generate a new file and use it as a mock file
    xmlFileWriter.WriteTo(filePath, dummyData);

    // Read from that file
    MyDummyClass fileContent = xmlFileReader.ReadFrom<MyDummyClass>(filePath);

    // Compare the result
    Assert.Equal(dummyData, fileContent);
}

Я борюсь с разделением реальной файловой системы. Как мне заставить класс XmlSerializer использовать поддельную файловую систему? Я установил пакет абстракций, но не знаю, как его использовать в этом случае (для чтения и записи).

1 Ответ

3 голосов
/ 04 августа 2020

StreamReader и StreamWriter оба имеют конструкторы, которые принимают Stream. Я рекомендую сделать ваш метод также принимать потоки в качестве параметров, и ваши модульные тесты могут предоставлять MemoryStream, содержащий ваш тест xml в виде строки (которая может быть жестко запрограммирована), в то время как ваше фактическое приложение может предоставлять a FileStream то есть файл на диске. Примерно так:

public void WriteTo<TSerializationData>(Stream location, TSerializationData data)
{
    // Code here doesn't change
}

public TSerializationData ReadFrom<TSerializationData>(Stream location)
{
    // Code here doesn't change
}

Тогда в ваших тестах вы можете сделать:

using (var ms = new MemoryStream())
{
    using (var sr = new StreamWriter())
    {
        sr.Write("<xml>This is your dummy XML string, can be anything you want</xml>");
    }

    MyDummyClass fileContent = xmlFileReader.ReadFrom<MyDummyClass>(ms);
}

И если вы хотите читать из файла, вы можете:

// Using whatever FileMode/ FileAccess you need
MyDummyClass fileContent;
using (var fs = File.Open(@"C:\Path\To\File.xml", FileMode.Open, FileAccess.Read))
{
    fileContent = xmlFileReader.ReadFrom<MyDummyClass>(fs);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...