This is certainly possible.
Para cambiar la estrategia para un solo tipo (MyClass
):
fixture.Customize<MyClass>(c => c.FromFactory(
new MethodInvoker(
new GreedyConstructorQuery())));
Para cambiar la estrategia a través del tablero:
fixture.Customizations.Add(
new MethodInvoker(
new GreedyConstructorQuery()));
Como resulta, sin embargo, utilizando GreedyConstructorQuery en general es muy problemático, como lo demuestra el siguiente fragmento de código. Imagínese una clase con este constructor:
public Foo(string name)
{
this.name = name;
}
Esta prueba será una excepción:
[Test]
public void GreedyConstructor()
{
Fixture fixture = new Fixture();
fixture.Customizations.Add(new MethodInvoker(new GreedyConstructorQuery()));
Foo foo = fixture.CreateAnonymous<Foo>();
}
La excepción lanzada es:
Ploeh.AutoFixture.ObjectCreationException: AutoFixture no pudo crear una instancia de System.SByte *, muy probablemente porque no tiene un constructor público, es un tipo abstracto o no público.
¿Qué significa eso del SByte *? No hay SByte * en Foo ...
Bueno, sí, sí. Al colocar MethodInvoker en la personalización, sobrescribe todas las estrategias de creación predeterminadas, incluida la de las cadenas. En su lugar, se va a buscar el constructor más codiciosos de cadena y que es:
public String(sbyte* value, int startIndex, int length, Encoding enc);
Y ahí está el sbyte * ...
Es todavía posible reemplazar la modesta algoritmo de selección constructor un algoritmo codicioso, es un poco más complicado de lo que me di cuenta por primera vez.
Lo que puede hacer es lo siguiente:
Escribir una pequeña clase como ésta:
public class GreedyEngineParts : DefaultEngineParts
{
public override IEnumerator<ISpecimenBuilder> GetEnumerator()
{
var iter = base.GetEnumerator();
while (iter.MoveNext())
{
if (iter.Current is MethodInvoker)
yield return new MethodInvoker(
new CompositeMethodQuery(
new GreedyConstructorQuery(),
new FactoryMethodQuery()));
else
yield return iter.Current;
}
}
}
y crear la instancia Fixture así:
Fixture fixture = new Fixture(new GreedyEngineParts());
que debería funcionar.
Bien, me gusta que pueda especificar el comportamiento para un tipo particular.Gracias – RichK
AutoFixture está realmente lanzando una ObjectCreationException cuando uso su segundo ejemplo, con el mensaje "AutoFixture no pudo crear una instancia de System.SByte * ..." Mi tipo de datos es muy simple y ciertamente no depende de un byte *! ¿Es esto un error o he usado mal el marco? – RichK
Lo he intentado, y todo funciona bien con tu primer ejemplo – RichK