Autofixture: Personalize com uma instrução lambda não funciona - é esperado?

Criado em 7 jun. 2018  ·  2Comentários  ·  Fonte: AutoFixture/AutoFixture

O seguinte teste falha:

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;
        }
    }

O parâmetro Control é preenchido por uma string aleatória em vez de um int gerado.

Versão 4.0 - 4.4 (não testei as anteriores)
Núcleo líquido 2.0 - 2.1

Isso funciona bem

[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 a personalização usando uma instrução lambda não funciona.
É um comportamento esperado?
E se sim, não deveria ser adicionado a alguma documentação? Perdi muito tempo tentando descobrir o que está errado ...

question

Todos 2 comentários

@ progala2 Obrigado por levantar a questão.

O comportamento existente é por design. A razão é que os métodos FromFactory , With (e Without ) são imutáveis ​​e, portanto, não alteram o objeto subjacente. Em vez disso, eles retornam um novo objeto com gráfico configurado.

A razão pela qual o primeiro teste não funciona é que você não usa o resultado das invocações, portanto, todas as alterações aplicadas são descartadas. Depois de reescrever o código corretamente, ele funcionará bem com as instruções também:

`` `c #
[Facto]
public void Test1 ()
{
var fixture = new Fixture ();
fixture.Customize(c =>
{
// uma declaração lambda
var res = c.FromFactory (() => novo PaymentReturnPayload (fixture.Create().Para sequenciar()));
res = res.Com (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 _));
}

Eu vejo, eles são imutáveis ​​- está muito claro agora.
Obrigado pela sua resposta e por algumas dicas adicionais!

Esta página foi útil?
0 / 5 - 0 avaliações