AutoFixture - 配置夹具限制字符串长度的一代 [英] AutoFixture - configure fixture to limit string generation length

查看:274
本文介绍了AutoFixture - 配置夹具限制字符串长度的一代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用autofixture构建方法​​对于某些类型的,我怎么能限制生成填补对象的字符串属性/字段中的字符串的长度?

When using autofixture Build method for some type, how can I limit the length of the strings generated to fill that objects string properties/fields?

推荐答案

随着构建方法本身,有没有那么多的选择,但你可以做这样的事情:

With the Build method itself, there aren't that many options, but you can do something like this:

var constrainedText = 
    fixture.CreateAnonymous<string>().Substring(0, 10);
var mc = fixture
    .Build<MyClass>()
    .With(x => x.SomeText, constrainedText)
    .CreateAnonymous();



不过,就个人而言,我不明白这是怎么更好或者更容易理解,这:

However, personally, I don't see how this is any better or easier to understand that this:

var mc = fixture
    .Build<MyClass>()
    .Without(x => x.SomeText)
    .CreateAnonymous();
mc.SomeText =
    fixture.CreateAnonymous<string>().Substring(0, 10);



就个人而言,我的很少的使用构建的方法,因为我更喜欢基于约定的方法来代替。 。这样做,至少有三种方式来约束字符串的长度

Personally, I very rarely use the Build method, since I prefer a convention-based approach instead. Doing that, there are at least three ways to constrain string length.

第一个选项就是约束的所有字符串的基

The first option is just to constrain the base of all strings:

fixture.Customizations.Add(
    new StringGenerator(() =>
        Guid.NewGuid().ToString().Substring(0, 10)));
var mc = fixture.CreateAnonymous<MyClass>();



以上定制截断所有生成的字符串为10个字符。然而,由于默认属性分配算法预先考虑的财产,以字符串的名字,最终的结果将是 mc.SomeText 将有类似SomeText3c12f144-5值为 ,所以这可能是你最想要的时候没有什么。

The above customization truncates all generated strings to 10 characters. However, since the default property assignment algorithm prepends the name of the property to the string, the end result will be that mc.SomeText will have a value like "SomeText3c12f144-5", so that is probably not what you want most of the time.

另一种方法是使用 [StringLength] 属性,如尼科斯所指出的:

Another option is to use the [StringLength] attribute, as Nikos points out:

public class MyClass
{
    [StringLength(10)]
    public string SomeText { get; set; }
}

这意味着,你可以不用明确说明对任何事情创建一个实例酒店的长度:

This means that you can just create an instance without explicitly stating anything about the property's length:

var mc = fixture.CreateAnonymous<MyClass>();



我能想到的第三个选项是我的最爱。这增加了专门针对会议指出,每当夹具被要求创建一个名为SomeText则会和字符串类型的属性值,结果字符串应该是完全10个字符长:

The third option I can think of is my favorite. This adds a specifically targeted convention that states that whenever the fixture is asked to create a value for a property with the name "SomeText" and of type string, the resulting string should be exactly 10 characters long:

public class SomeTextBuilder : ISpecimenBuilder
{
    public object Create(object request, ISpecimenContext context)
    {
        var pi = request as PropertyInfo;
        if (pi != null && 
            pi.Name == "SomeText" &&
            pi.PropertyType == typeof(string))

            return context.Resolve(typeof(string))
                .ToString().Substring(0, 10);

        return new NoSpecimen(request);
    }
}



用法:

Usage:

fixture.Customizations.Add(new SomeTextBuilder());
var mc = fixture.CreateAnonymous<MyClass>();



这种方法的优点在于它独自离开SUT,仍然不影响任何其他字符串值。

The beauty of this approach is that it leaves the SUT alone and still doesn't affect any other string values.

您可以概括这个 SpecimenBuilder 任何类和长度,像这样:

You can generalize this SpecimenBuilder to any class and length, like so:

public class StringPropertyTruncateSpecimenBuilder<TEntity> : ISpecimenBuilder
{
    private readonly int _length;
    private readonly PropertyInfo _prop;

    public StringPropertyTruncateSpecimenBuilder(Expression<Func<TEntity, string>> getter, int length)
    {
        _length = length;
        _prop = (PropertyInfo)((MemberExpression)getter.Body).Member;
    }

    public object Create(object request, ISpecimenContext context)
    {
        var pi = request as PropertyInfo;

        return pi != null && AreEquivalent(pi, _prop)
            ? context.Create<string>().Substring(0, _length)
            : (object) new NoSpecimen(request);
    }

    private bool AreEquivalent(PropertyInfo a, PropertyInfo b)
    {
        return a.DeclaringType == b.DeclaringType
               && a.Name == b.Name;
    }
}



用法:

Usage:

fixture.Customizations.Add(
    new StringPropertyTruncateSpecimenBuilder<Person>(p => p.Initials, 5));

这篇关于AutoFixture - 配置夹具限制字符串长度的一代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆