I\'ve just started to use AutoFixture.AutoMoq in my unit tests and I\'m finding it very helpful for creating objects where I don\'t care about the specific
Good thread, I added another twist based on many of the aswers already posted:
Example:
var sut = new Fixture()
.For()
.Set("value1").To(aInterface)
.Set("value2").ToEnumerableOf(22, 33)
.Create();
Test classes:
public class AClass
{
public AInterface Value1 { get; private set; }
public IEnumerable Value2 { get; private set; }
public AClass(AInterface value1, IEnumerable value2)
{
Value1 = value1;
Value2 = value2;
}
}
public interface AInterface
{
}
Full test
public class ATest
{
[Theory, AutoNSubstituteData]
public void ATestMethod(AInterface aInterface)
{
var sut = new Fixture()
.For()
.Set("value1").To(aInterface)
.Set("value2").ToEnumerableOf(22, 33)
.Create();
Assert.True(ReferenceEquals(aInterface, sut.Value1));
Assert.Equal(2, sut.Value2.Count());
Assert.Equal(22, sut.Value2.ElementAt(0));
Assert.Equal(33, sut.Value2.ElementAt(1));
}
}
Extension method:
public static class AutoFixtureExtensions
{
public static SetCreateProvider For(this IFixture fixture)
{
return new SetCreateProvider(fixture);
}
}
Classes participating in the fluent style:
public class SetCreateProvider
{
private readonly IFixture _fixture;
public SetCreateProvider(IFixture fixture)
{
_fixture = fixture;
}
public SetProvider Set(string parameterName)
{
return new SetProvider(this, parameterName);
}
public TTypeToConstruct Create()
{
var instance = _fixture.Create();
return instance;
}
internal void AddConstructorParameter(ConstructorParameterRelay constructorParameter)
{
_fixture.Customizations.Add(constructorParameter);
}
}
public class SetProvider
{
private readonly string _parameterName;
private readonly SetCreateProvider _father;
public SetProvider(SetCreateProvider father, string parameterName)
{
_parameterName = parameterName;
_father = father;
}
public SetCreateProvider To(TTypeOfParam parameterValue)
{
var constructorParameter = new ConstructorParameterRelay(_parameterName, parameterValue);
_father.AddConstructorParameter(constructorParameter);
return _father;
}
public SetCreateProvider ToEnumerableOf(params TTypeOfParam[] parametersValues)
{
IEnumerable actualParamValue = parametersValues;
var constructorParameter = new ConstructorParameterRelay>(_parameterName, actualParamValue);
_father.AddConstructorParameter(constructorParameter);
return _father;
}
}
Constructor parameter relay from other answers:
public class ConstructorParameterRelay : ISpecimenBuilder
{
private readonly string _paramName;
private readonly TValueType _paramValue;
public ConstructorParameterRelay(string paramName, TValueType paramValue)
{
_paramName = paramName;
_paramValue = paramValue;
}
public object Create(object request, ISpecimenContext context)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
ParameterInfo parameter = request as ParameterInfo;
if (parameter == null)
return new NoSpecimen();
if (parameter.Member.DeclaringType != typeof(TTypeToConstruct) ||
parameter.Member.MemberType != MemberTypes.Constructor ||
parameter.ParameterType != typeof(TValueType) ||
parameter.Name != _paramName)
return new NoSpecimen();
return _paramValue;
}
}