首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AutoFixture:如何使用通用的测试数据集来生成不同的对象?

AutoFixture:如何使用通用的测试数据集来生成不同的对象?
EN

Stack Overflow用户
提问于 2019-01-03 09:38:03
回答 2查看 550关注 0票数 1

我想测试一个自己编写的XML解析器,这个解析器使用XML字符串并返回模型表示。

代码语言:javascript
复制
T Parse(string content);

我遇到的问题是关于我测试的断言部分。因为每次我调用Create<T>()时,它都会生成新的随机数据,在这种情况下,这不是我想要的。我需要一个可以按以下顺序使用的通用测试数据集:

)生成可以传递给我的解析器的XML字符串。

b)使用相同的测试数据集生成模型表示

( c)将XML解析器结果与生成的模型表示和Assert.AreEqual()进行比较

我偶然发现了Freeze<T>()方法,它“听起来”符合我的目的。然而,我不知道如何使用它。

因此,问题是:如何使用公共测试数据集生成不同的对象?

这是我当前的方法和静态测试数据生成器类。

代码语言:javascript
复制
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;
    }
}

这就是我想测试解析器的方法。我希望我正在努力实现的目标是清楚的。

代码语言:javascript
复制
[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); 
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-03 19:12:11

在测试解析器时,我常常发现从基于属性的测试剧本中获取页面是最容易的。许多用于基于属性的测试的技术在AutoFixture中也很有用。

在对解析逻辑进行基于属性的测试时,定义与解析器匹配的序列化程序通常是有用的。也就是说,可以将给定的模型转换为解析器所解析的格式的函数。在这种情况下,它将是一个XML序列化程序。

指示AutoFixture (或基于属性的测试库)创建“模型”对象的有效实例通常要容易得多,而不是指示它生成有效的XML字符串。

一旦设置了AutoFixture,就可以让它创建模型的实例,然后序列化模型,并让解析器解析序列化的模型。断言是,被解析的模型应该等于输入模型。

Scott称这种测试模式为一次又一次。您还可以使用我博客上的例子看到FsCheck。

使用AutoFixture,它可能如下所示:

代码语言:javascript
复制
[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);
}

(我还没有试过编译,所以可能会有打字.)

票数 0
EN

Stack Overflow用户

发布于 2019-01-03 10:14:40

我不能100%确定这是否是您想要的,但是也许可以为您的XML数据创建一个具有自定义类型的定制夹具--数据是一种选择?

代码语言:javascript
复制
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一起工作,而不是不使用,但我在不久前的一个项目中遇到了一些问题,而上面的解决方案对我来说更可靠。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54019615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档