AutoFixture可以从提供的数据集生成随机字符串/文本吗?

时间:2016-02-08 02:48:51

标签: c# .net autofixture

可以使用AutoFixture为字符串属性生成随机数据..但它来自固定数据源?

例如:我有30个街道名称硬编码到内存集合(数组/列表/其他)。然后,对于我的Address实例,StreetName属性不仅仅是一个随机字符串值(这是AutoFixture的默认结果),而是来自该硬编码集合的街道名称之一。

我的第一个想法是使用AutoFixture可能创建的随机数..这个数字在数组长度/大小内...所以实际上我随机化一个数组插槽。然后,使用此随机数,获取集合/数组槽的值(也称为街道名称)(即,给定索引器,获取该索引位置的值)。

这是怎么做的?

1 个答案:

答案 0 :(得分:0)

与关于AutoFixture的许多其他事情一样,如果你能use more explicit domain modelling,事情会变得容易多了。不是将table variable建模为StreetName,而是为其引入域对象:

string

这是C#和Java中令人痛苦的建模步骤之一,但在F#或Haskell中会是一个单行...

但是,我们假设我们有一个预定义的街道名称列表:

public sealed class StreetName
{
    private readonly string value;

    public StreetName(string streetName)
    {
        value = streetName ?? throw new ArgumentNullException(nameof(streetName));
    }

    public override bool Equals(object obj)
    {
        var other = obj as StreetName;
        if (other == null)
            return base.Equals(obj);

        return Equals(value, other.value);
    }

    public override int GetHashCode()
    {
        return value.GetHashCode();
    }

    public override string ToString()
    {
        return value;
    }

    public static implicit operator string(StreetName streetAddress)
    {
        return streetAddress.value;
    }

    public static implicit operator StreetName(string streetAddress)
    {
        return new StreetName(streetAddress);
    }
}

现在,您可以使用public static class StreetNames { public static IEnumerable<string> Values = new[] { "221 B Baker St.", "1313 Webfoot Walk", "420 Paper St.", "42 Wallaby Way" /* More addresses go here... */ }; } 轻松告诉AutoFixture仅从该列表中选择:

ElementsBuilder

此时,这意味着当您使用自动混合创建var fixture = new Fixture(); fixture.Customizations.Add( new ElementsBuilder<StreetName>(StreetNames.Values.Select(s => (StreetName)s))); 值时,它会从StreetName中选择,但是当它仍然不会这样做时你要求它创建StreetNames.Values值。你可以用一点Address来解决(哈哈)这个问题:

ISpecimenBuilder

现在您可以像这样配置public class StreetNameBuilder : ISpecimenBuilder { public object Create(object request, ISpecimenContext context) { var pi = request as PropertyInfo; if (pi == null || pi.Name != "StreetName" || pi.PropertyType != typeof(string)) return new NoSpecimen(); var sn = context.Resolve(typeof(StreetName)); return (string)(StreetName)sn; } }

Fixture

现在,它会创建var fixture = new Fixture(); fixture.Customizations.Add( new ElementsBuilder<StreetName>(StreetNames.Values.Select(s => (StreetName)s))); fixture.Customizations.Add(new StreetNameBuilder()); 个值,并从预定义列表中选择Address个值。

如果您无法更改域模型,则仍可以添加类似StreetName的类。只需将其添加到测试代码库而不是生产代码库。