Autofixture: Personalizar con una declaración lambda no funciona, ¿se espera?

Creado en 7 jun. 2018  ·  2Comentarios  ·  Fuente: AutoFixture/AutoFixture

La siguiente prueba falla:

public class UnitTest1
    {
        [Fact]
        public void Test1()
        {
            var fixture = new Fixture();
            fixture.Customize<PaymentReturnPayload>(c =>
            { // a statement lambda
                c.With(a => a.OperationAmount, "1");
                c.FromFactory(() => new PaymentReturnPayload(fixture.Create<int>().ToString()));
                return c;
            });
            var paymentReturnPayload = fixture.Create<PaymentReturnPayload>();
            Assert.True(int.TryParse(paymentReturnPayload.Control, out _));
        }
    }

    public class PaymentReturnPayload
    {
        public PaymentReturnPayload(string control)
        {
            Control = control;
        }

        public string OperationAmount { get; set; }

        public string Control
        {
            get;
        }
    }

El parámetro Control se completa con una cadena aleatoria en lugar de int generado.

Versión 4.0 - 4.4 (no probé las anteriores)
Net core 2.0 - 2.1

Esto funciona bien

[Fact]
        public void Test1()
        {
            var fixture = new Fixture();
            fixture.Customize<PaymentReturnPayload>(c =>
                c.FromFactory(() => new PaymentReturnPayload(fixture.Create<int>().ToString())));
            var paymentReturnPayload = fixture.Create<PaymentReturnPayload>();
            Assert.True(int.TryParse(paymentReturnPayload.Control, out _));
        }

Parece que la personalización con una instrucción lambda no funciona.
¿Es un comportamiento esperado?
Y si es así, ¿no debería agregarse a alguna documentación? Perdí mucho tiempo averiguando qué estaba mal ...

question

Todos 2 comentarios

@ progala2 Gracias por plantear la pregunta.

El comportamiento existente es por diseño. La razón es que los métodos FromFactory , With (y Without ) son inmutables, por lo que no cambian el objeto subyacente. En su lugar, devuelven un nuevo objeto con un gráfico configurado.

La razón por la que la primera prueba no funciona es que no usa el resultado de las invocaciones, por lo que todos los cambios aplicados se descartan. Una vez que reescriba el código correctamente, también funcionará bien con las declaraciones:

`` c #
[Hecho]
prueba de vacío público1 ()
{
var fixture = new Fixture ();
accesorio Personalizar(c =>
{
// una declaración lambda
var res = c.FromFactory (() => new PaymentReturnPayload (fixture.Create().Encadenar()));
res = res.With (a => a.OperationAmount, "1");
return res;
});

var paymentReturnPayload = fixture.Create<PaymentReturnPayload>();
Assert.True(int.TryParse(paymentReturnPayload.Control, out _));

}


But as you might notice, it's easier to write this code with lambda.

P.S. By the way, you can slightly improve the final code (notice the `FromFactory` has overload taking extra values necessary for the object construction):
```c#
[Fact]
public void Test3()
{
    var fixture = new Fixture();
    fixture.Customize<PaymentReturnPayload>(c =>
        c.FromFactory((int control) => new PaymentReturnPayload(control.ToString())));

    var paymentReturnPayload = fixture.Create<PaymentReturnPayload>();
    Assert.True(int.TryParse(paymentReturnPayload.Control, out _));
}

Ya veo, son inmutables, ahora está mucho más claro.
¡Gracias por tu respuesta y algunos consejos adicionales!

¿Fue útil esta página
0 / 5 - 0 calificaciones