我想测试一个自写的XML解析器,该解析器需要一个XML字符串并返回其模型表示。
T Parse(string content);
我遇到的问题与测试的断言部分有关。因为每次我调用Create<T>()
时,它都会生成新的随机数据,在这种情况下,这不是我想要的。我有点需要可以按以下顺序使用的通用测试数据集:
a)生成可以传递给我的解析器的XML字符串
b)使用相同的测试数据集生成模型表示形式
c)比较XML解析器结果与生成的模型表示形式和Assert.AreEqual()
我遇到了Freeze<T>()
方法,它听起来“听起来”很适合我的目的。但是我不知道如何使用它。
所以问题是:如何使用通用的测试数据集来生成不同的对象?
这是我当前的方法和静态测试数据生成器类。
public static class TestDataGenerator
{
public static string GenerateSyntheticXmlTestData<T>(int minOid, int maxOid, int amount = 5)
{
var fixture = new Fixture()
{
RepeatCount = amount
};
fixture.Customizations.Add(new OidGenerator(minOid, maxOid));
fixture.Customizations.Add(new EnableAllProperties());
var testData = fixture.Create<T>();
var serializedXmlTestData = XmlSerializerHelper.Current.SerializeToXmlDocument(testData, Encoding.UTF8);
return serializedXmlTestData;
}
public static ICollection<T> GenerateSyntheticModelTestData<T>(int minOid, int maxOid, int amount = 1)
{
var fixture = new Fixture()
{
RepeatCount = 1
};
fixture.Customizations.Add(new OidGenerator(minOid, maxOid));
var testData = fixture.CreateMany<T>(amount).ToList();
return testData;
}
}
这就是我想测试解析器的方式。我希望清楚我正在努力实现的目标。
[Fact]
public void ShouldParse()
{
// [...]
var xmlContent = TestDataGenerator.GenerateSyntheticXmlTestData<MyType>(minOid: 1, maxOid: 100, amount: 5);
// Here I would like to generate a model object using the same data
//
// var modelContent = new Fixture().Create<ModelType>();
var parsedContent = parser.Parse(xmlContent);
//parsedContent.Should().BeEquivalentTo(modelContet);
}
答案 0 :(得分:0)
我不确定100%是否是您要找的东西,但是也许可以为您的XML数据创建具有自定义类型的自定义固定装置?
public class CustomFixture : Fixture
{
Customize<YourXmlType>(c => c.Without(f => f.XmlStringThatShouldNotBeGenerated));
Customize<YourXmlType>(c => c.Do(f => f.XmlStringThatShouldNotBeGenerated = "Your shared xml string"));
}
这也可以用c.With
代替“不做而做”,但是一段时间前我在一个项目中遇到了问题,上述解决方案对我来说更可靠。
答案 1 :(得分:0)
在测试解析器时,我经常发现从基于属性的测试手册中提取页面最简单。 AutoFixture也可以使用许多对基于属性的测试有用的技术。
进行基于属性的解析逻辑测试时,定义与解析器一起使用的序列化程序通常很有用。也就是说,该函数可以将给定模型转换为解析器解析的格式。在这种情况下,它将是XML序列化程序。
指示AutoFixture(或基于属性的测试库)创建“模型”对象的有效实例通常要比指示其生成有效的XML字符串容易得多。
一旦设置了AutoFixture,就可以让它创建模型的实例,然后序列化模型,然后让解析器解析序列化的模型。断言是解析后的模型应该等于输入模型。
Scott Wlaschin将此测试模式称为There and back again。您还可以使用FsCheck查看example of it on my blog。
使用AutoFixture,可能看起来像这样:
[Fact]
public void RoundTrippingWorks()
{
var fixture = new Fixture().Customize(/*...*/);
var model = fixture.Create<MyModel>();
string xml = MyXmlSerializer.Serialize(model);
MyModel actual = MyXmlParser.Parse(xml);
Assert.Equal(model, actual);
}
(我没有尝试编译它,所以可能会有错别字...)