Tricks
This page contains a list of tips and tricks to be used when dealing with special scenarios with AutoFixture
In case a certain type can assume a subset of the valid values, an instance of the
ElementsBuilder<T>
class can be used to provide AutoFixture with the values to fish from.[Test]
public void ElementsBuilder_returns_one_of_specified_values()
{
// ARRANGE
var fixture = new Fixture();
var values = new[] { "Foo", "Bar", "Baz" };
fixture.Customizations.Add(new ElementsBuilder<string>(values));
// ACT
var value = fixture.Create<string>();
// ASSERT
Assert.That(value, Is.AnyOf(values));
}
It's important to note that a setup like the one above affects every instance of the customized type: this means that every instance of the customized type generated by this fixture will be picked from the specified values.
By default, when requested an instance of type
Encoding
, AutoFixture always returns Encoding.UTF8
.It is possible to override the default setup by registering all supported encodings. To do so, we add an instance of
ElementsBuilder<EncodingInfo>
to the set of customizations. We can then use Register
to instruct AutoFixture to extract an Encoding
from the random EncodingInfo
received.fixture.Customizations.Add(new ElementsBuilder<EncodingInfo>(Encoding.GetEncodings()));
fixture.Register<EncodingInfo, Encoding>((EncodingInfo ei) => ei.GetEncoding());
Furthermore, we can use the above configuration to configure the string property of an object that could be parsed from a text file.
fixture.Customize<Options>(c => c.With(p => p.EncodingName, (Encoding encoding) => encoding.WebName));
Here is the class used for this example
public class Options
{
public string EncodingName { get; set; }
}
Classes exposing properties of type
Stream
require special setup.Here are some configurations that can be used when working with streams. The best setup might vary from case to case.
The following class will be used for the snippets below
public class Options
{
public Stream InputStream { get; set; }
}
The easiest scenario: every
Stream
property receives the singleton value of the NullStream
class.fixture.Inject<Stream>(Stream.Null);
If a more targeted approach is needed, the construct
With
can be used.fixture.Customize<Options>(c => c.With(p => p.InputStream, Stream.Null));
In case the system under test expects some data out of the stream, the
MemoryStream
can be used to return the test data.This setup will return a stream containing a certain amount of bytes. The amount is controlled by the
Fixture.RepeatCount
property.fixture.Register<byte[], Stream>((byte[] data) => new MemoryStream(data));
In the case the stream is expected to contain a random string, this setup can be used.
fixture.Register<string, Stream>((string data) =>
{
var bytes = Encoding.UTF8.GetBytes(data);
return new MemoryStream(bytes);
});
Finally, if the stream is expected to contain the serialized version of some data, this setup can be used (the example uses Newtonsoft.Json to serialize the payload)
fixture.Register<Data, Stream>((Data data) =>
{
var serializer = new JsonSerializer();
var ms = new MemoryStream();
var sr = new StreamWriter(ms);