gpt4 book ai didi

c# - AutoFixture - 配置夹具以限制字符串生成长度

转载 作者:IT王子 更新时间:2023-10-29 04:03:24 25 4
gpt4 key购买 nike

当对某些类型使用 AutoFixture 的 Build 方法时,如何限制生成的字符串的长度以填充该对象的字符串属性/字段?

最佳答案

Build 方法本身并没有那么多选项,但您可以这样做:

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

但是,就我个人而言,我看不出这有什么更好或更容易理解:

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

就个人而言,我很少使用Build 方法,因为我更喜欢基于约定的方法。为此,至少有三种方法可以限制字符串长度。

第一个选项只是限制所有字符串的基数:

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

以上自定义将所有生成的字符串截断为 10 个字符。但是,由于默认的属性分配算法将属性名称添加到字符串前面,最终结果将是 mc.SomeText 的值类似于“SomeText3c12f144-5”,所以这可能不是大多数时候你想要什么。

另一种选择是使用 [StringLength] 属性,正如 Nikos 指出的那样:

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

这意味着您可以只创建一个实例而无需明确说明属性的长度:

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

我能想到的第三个选项是我最喜欢的。这添加了一个专门针对的约定,该约定规定每当要求 fixture 为名称为“SomeText”且类型为字符串的属性创建值时,生成的字符串的长度应恰好为 10 个字符:

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();
}
}

用法:

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

这种方法的美妙之处在于它让 SUT 单独存在并且仍然不影响任何其他字符串值。


您可以将此 SpecimenBuilder 概括为任何类和长度,如下所示:

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)
: new NoSpecimen();
}

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

用法:

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

关于c# - AutoFixture - 配置夹具以限制字符串生成长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10125199/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com