When using AutoFixture's Build method for some type, how can I limit the length of the strings generated to fill that object's string properties/fields?
11 Answers
With the Build
method itself, there aren't that many options, but you can do something like this:
var constrainedText =
fixture.Create<string>().Substring(0, 10);
var mc = fixture
.Build<MyClass>()
.With(x => x.SomeText, constrainedText)
.Create();
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)
.Create();
mc.SomeText =
fixture.Create<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.Create<MyClass>();
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.
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.Create<MyClass>();
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();
}
}
Usage:
fixture.Customizations.Add(new SomeTextBuilder());
var mc = fixture.Create<MyClass>();
The beauty of this approach is that it leaves the SUT alone and still doesn't affect any other string values.
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)
: new NoSpecimen();
}
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));

- 4,941
- 2
- 41
- 65

- 225,310
- 48
- 427
- 736
-
The customization's approach to change how StringGenerator behaves is spot on. Thanks! – Ricardo Rodrigues Apr 14 '12 at 12:16
-
1But this approach won't generate strings that are _longer_ than the AF string convention.. – Peter McEvoy Nov 17 '15 at 10:21
-
3Update: The fixture.CreateAnonymous method is now deprecated, one should use Create
instead – Sudhanshu Mishra Apr 09 '16 at 23:48 -
Yea as pointed out by @PeterMcEvoy, this doesn't answer the case where you want a longer string. – Jim Aho Oct 11 '16 at 14:35
-
You can just hook up @PeterMcEvoy 's `GetRandomChar()` instead of `context.Create...Substring()` if you want bigger string – aateeque Oct 02 '18 at 13:52
If maximum length is a constraint and you own the source code for the type, you can use the StringLengthAttribute class to specify the maximum length of characters that are allowed.
From version 2.6.0, AutoFixture supports DataAnnotations and it will automatically generate a string with the maximum length specified.
As an example,
public class StringLengthValidatedType
{
public const int MaximumLength = 3;
[StringLength(MaximumLength)]
public string Property { get; set; }
}
[Fact]
public void CreateAnonymousWithStringLengthValidatedTypeReturnsCorrectResult()
{
// Fixture setup
var fixture = new Fixture();
// Exercise system
var result = fixture.CreateAnonymous<StringLengthValidatedType>();
// Verify outcome
Assert.True(result.Property.Length <= StringLengthValidatedType.MaximumLength);
// Teardown
}
The above test will also pass when using Build (to customize the creation algorithm for a single object):
var result = fixture.Build<StringLengthValidatedType>().CreateAnonymous();

- 10,868
- 2
- 46
- 80
-
This is not flexible, you have to create one type for each length you need? not real world usable. – Ricardo Rodrigues Apr 14 '12 at 12:14
-
No, you don't have to create anything. Just use the [StringLength] attribute on the property you wish. (AutoFixture will then automatically generate a string for the given length.) – Nikos Baxevanis Apr 15 '12 at 08:48
-
4I don't want to pollute my DTOs with test attributes, doesn't make sense to me. – Ricardo Rodrigues Apr 16 '12 at 17:08
-
7But are they "test attributes"? In my case I'd be describing the maximum length the persistence back end allowed the property to be. – Sam Feb 13 '13 at 06:47
Here is my solution. When it doesn't matter what the string contains then I'm using this method:
public static string GetStringOfLength(this IFixture fixture, int length)
{
return string.Join("", fixture.CreateMany<char>(length));
}
It's short and it works for me.

- 91
- 1
- 2
Here's a specimen builder that can generate random strings of arbitrary length - even longer than the Guid+PropertyName strings that are by default. Also, you can choose the subset of chars you want to use and even pass in your own random (so that you can control the seed if you need to)
public class RandomStringOfLengthRequest
{
public RandomStringOfLengthRequest(int length) : this(length, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890 !?,.-")
{
}
public RandomStringOfLengthRequest(int length, string charactersToUse): this(length, charactersToUse, new Random())
{
}
public RandomStringOfLengthRequest(int length, string charactersToUse, Random random)
{
Length = length;
Random = random;
CharactersToUse = charactersToUse;
}
public int Length { get; private set; }
public Random Random { get; private set; }
public string CharactersToUse { get; private set; }
public string GetRandomChar()
{
return CharactersToUse[Random.Next(CharactersToUse.Length)].ToString();
}
}
public class RandomStringOfLengthGenerator : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
if (request == null)
return new NoSpecimen();
var stringOfLengthRequest = request as RandomStringOfLengthRequest;
if (stringOfLengthRequest == null)
return new NoSpecimen();
var sb = new StringBuilder();
for (var i = 0; i < stringOfLengthRequest.Length; i++)
sb.Append(stringOfLengthRequest.GetRandomChar());
return sb.ToString();
}
}
You then can use it to populate a property of an object like this:
var input = _fixture.Build<HasAccountNumber>()
.With(x => x.AccountNumber,
new SpecimenContext(new RandomStringOfLengthGenerator())
.Resolve(new RandomStringOfLengthRequest(50)))
.Create();

- 2,816
- 19
- 24
Note: This solution does not really use AutoFixture, but sometimes it's harder to use the package then just to program it yourself.
Why use AF when it's harder and uglier to use AF, my preferred usage is:
var fixture = new Fixture();
fixture.Create<string>(length: 9);
So I created an extension method:
public static class FixtureExtensions
{
public static T Create<T>(this IFixture fixture, int length) where T : IConvertible, IComparable, IEquatable<T>
{
if (typeof(T) == typeof(string))
{
// there are some length flaws here, but you get the point.
var value = fixture.Create<string>();
if (value.Length < length)
throw new ArgumentOutOfRangeException(nameof(length));
var truncatedValue = value.Substring(0, length);
return (T)Convert.ChangeType(truncatedValue, typeof(T));
}
// implement other types here
throw new NotSupportedException("Only supported for strings (for now)");
}
}

- 12,902
- 7
- 57
- 75
-
well but that's a workaround, not idiomatic AutoFixture really. – Ricardo Rodrigues Dec 07 '18 at 08:10
-
-
-
This question is on how to do it with AF, that's beyond the scope :) – Ricardo Rodrigues Dec 21 '18 at 10:10
-
True that, but still want to have this answer to tell people that you don't have to solve everything with the package you are using if it's easier not to do it. Added a note. – Nick N. Dec 21 '18 at 15:33
-
1I upvoted, because I think you nailed the API, but can see why everyone else downvoted (bypassing AutoFixture). It seems ISpecimenBuilder should be aware of a special length property. Canonical use case would be `Fixture.Create
(length: 50);` for light-weight fixture creation inline in a test case. – John Zabroski May 27 '19 at 20:20
I added a custom string builder to my project. It appends a 4 digit number instead of a guid.
public class StringBuilder : ISpecimenBuilder
{
private readonly Random rnd = new Random();
public object Create(object request, ISpecimenContext context)
{
var type = request as Type;
if (type == null || type != typeof(string))
{
return new NoSpecimen();
}
return rnd.Next(0,10000).ToString();
}
}

- 5,420
- 6
- 28
- 54
Some of the other solutions are pretty good, but if you're generating objects in a test fixture based on a data model, there are other issues you'll run into. First, the StringLength attribute isn't a great option for a code-first data model because it adds seemingly duplicate annotations. It's not readily apparent why you need both StringLength and MaxLength. Keeping them in sync manually is rather redundant.
I would lean towards customizing how the Fixture works.
1) You can Customize the fixture for a class and specify that when creating that property, you truncate the string, as needed. So to truncate the FieldThatNeedsTruncation in the MyClass to 10 characters, you would use the following:
fixture.Customize<MyClass>(c => c
.With(x => x.FieldThatNeedsTruncation, Fixture.Create<string>().Substring(0,10));
2) The problem with the first solution is that you still need to keep the length in sync, only now your probably doing it in two entirely different classes rather than in two lines of consecutive data annotations.
The second option that I came up with to generate data from an arbitrary Data Model without having to manually set it in each customization you declare is to use a custom ISpecimenBuilder that evaluates the MaxLengthAttribute directly. Here's the source code for a class that I modified from the library itself, which was evaluating the StringLengthAttribute.
/// <summary>
/// Examine the attributes of the current property for the existence of the MaxLengthAttribute.
/// If set, use the value of the attribute to truncate the string to not exceed that length.
/// </summary>
public class MaxLengthAttributeRelay : ISpecimenBuilder
{
/// <summary>
/// Creates a new specimen based on a specified maximum length of characters that are allowed.
/// </summary>
/// <param name="request">The request that describes what to create.</param>
/// <param name="context">A container that can be used to create other specimens.</param>
/// <returns>
/// A specimen created from a <see cref="MaxLengthAttribute"/> encapsulating the operand
/// type and the maximum of the requested number, if possible; otherwise,
/// a <see cref="NoSpecimen"/> instance.
/// Source: https://github.com/AutoFixture/AutoFixture/blob/ab829640ed8e02776e4f4730d0e72ab3cc382339/Src/AutoFixture/DataAnnotations/StringLengthAttributeRelay.cs
/// This code is heavily based on the above code from the source library that was originally intended
/// to recognized the StringLengthAttribute and has been modified to examine the MaxLengthAttribute instead.
/// </returns>
public object Create(object request, ISpecimenContext context)
{
if (request == null)
return new NoSpecimen();
if (context == null)
throw new ArgumentNullException(nameof(context));
var customAttributeProvider = request as ICustomAttributeProvider;
if (customAttributeProvider == null)
return new NoSpecimen();
var maxLengthAttribute = customAttributeProvider.GetCustomAttributes(typeof(MaxLengthAttribute), inherit: true).Cast<MaxLengthAttribute>().SingleOrDefault();
if (maxLengthAttribute == null)
return new NoSpecimen();
return context.Resolve(new ConstrainedStringRequest(maxLengthAttribute.Length));
}
}
Then simply add it as a Customization, as follows:
fixture.Customizations.Add(new MaxLengthAttributeRelay());

- 833
- 6
- 21
You can use StringLength
attribute:
public class MyData
{
[System.ComponentModel.DataAnnotations.StringLength(42)]
public string Description { get; set; }
}
and then use fixture as usual
var fixture = new Fixture();
var mockData = fixture.Create<MyData>();

- 1,105
- 8
- 19
Here is my solution, and notes.
First, it is clear that there is some tight coupling in AutoFixture.Create to knowledge of how a specimen is built and customized. For strings, it's annoying because we know the default is a Guid. Using this knowledge, I created a Func that handles this in my test cases:
private readonly Func<IFixture, int, string> _createString = (IFixture fixture, int length) => (fixture.Create<string>() + fixture.Create<string>()).Substring(0, length);
This could be inductively defined to exploit the guid generated by Auto-Fixture by default. It is 36 characters by default, so:
private readonly Func<IFixture, int, string> _createString = (IFixture fixture, int length) =>
{
if (length < 0) throw new ArgumentOutOfRangeException(nameof(length));
var sb = new StringBuilder();
const int autoFixtureStringLength = 36;
var i = length;
do
{
sb.Append(fixture.Create<string>());
i -= autoFixtureStringLength;
} while (i > autoFixtureStringLength && i % autoFixtureStringLength > 0);
sb.Append(fixture.Create<string>());
return (sb).ToString().Substring(0, length);
};
Again, the whole premise to this solution is that AutoFixture is already tightly coupled to whatever object creation policy you have. All you are doing is dove-tailing on that.
It would probably be ideal if AutoFixture exposed a "min value" and "max value" extension point to query. This is sort of what functional testing frameworks like QuickCheck do, and then let you 'shrink' the value.

- 2,212
- 2
- 28
- 54
There are two methods I use. The first one which I don't use often would change the string generation format for all strings. You do this by registering a new creation function
fixture.Register<string>(() => Guid.NewGuid().ToString().Substring(0, 10));
var s = fixture.Create<string>();
But the second way I do this is a lot more flexible in my opinion as you don't register any construction functions and it applies just to the one string you are creating. Simply create an array of chars and pass this into the string constructor.
var s = new string(fixture.CreateMany<char>(10).ToArray());

- 11
- 1
I feel like this is a really simple solution. It uses another instance of Fixture to create the string, but does it all inline so it's readable.
var result = Fixture.Build<MyObject>()
.With(x => x.MyString, new List<string> { Fixture.Create<string>().Substring(0, 3) })
.Create();

- 2,436
- 1
- 19
- 25