AutoFixture - 配置夹具限制字符串长度的一代 [英] AutoFixture - configure fixture to limit string generation length
问题描述
在使用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屋!