Profile Image

Carlos Vigueras

Senior Backend Developer

Testing – Patrón Object Mother con AutoFixture

En esta entrada, la cual va a ser bastante sencilla, os voy a hablar del Patrón Object Mother, combinado con AutoFixture, y si, os lo podéis imaginar, es tan simple como usar dicho Patrón y en él implementar AutoFixture.

De este modo aprovechamos, por un lado, la semántica que le damos a los Tests con el patrón Object Mother, y por el otro la versatilidad que nos ofrece AutoFixture.

Para implementar esta técnica simplemente hemos de usar dentro de las clases del patrón Object Mother la librería de AutoFixture, y dicha combinación nos va a facilitar mucho el desarrollo de nuestros Tests.

Como siempre vamos a ver un ejemplo y así lo veremos todo mas claro.

Voy a utilizar el ejemplo de Object Mother, modificándolo, y añadiéndole AutoFixture a los ejemplos, de este modo vamos a ver lo sencillo que es:

User.cs

    public class User
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public User(string name, int age)
        {
            Name = name;
            Age = age;
        }
        public static User Create(string name, int age)
        {
            return new User(name, age);
        }
    }Lenguaje del código: JavaScript (javascript)

Home.cs

    public class Home
    {
        public string Access(User user)
        {
            switch (user.Age)
            {
                case < 18:
                    return "Aplicación web solo para personas mayores de edad";
                case < 30:
                    return "Consigue un descuento de 20€ en tu primer pedido";
                case < 65:
                    return "Consigue un descuento de 25€ en tu primer pedido";
                case > 65:
                    return "Consigue un descuento de 30€ en tu primer pedido";
                default:
                    return string.Empty;
            }
        }
    }Lenguaje del código: PHP (php)

UserShould.cs

public partial class UserShould
{
    private Home home;
    [SetUp]
    public void Setup()
    {
        home = new Home();
    }

    [Test]
    public void get_message_under_eighteen_years()
    {
        //Given
        var givenUserUnderEighteen = UserMother.UserUnderEighteen();

        //When
        var message = home.Access(givenUserUnderEighteen);

        //Then
        Assert.IsTrue(string.Equals(message, "Aplicación web solo para personas mayores de edad",
            StringComparison.OrdinalIgnoreCase));
    }

    [Test]
    public void get_message_over_eighteen_under_thirty_years()
    {
        //Given
        var givenUserOverEighteenUnderThirty = UserMother.UserOverEighteenUnderThirty();

        //When
        var message = home.Access(givenUserOverEighteenUnderThirty);

        //Then
        Assert.IsTrue(string.Equals(message, "Consigue un descuento de 20€ en tu primer pedido",
            StringComparison.OrdinalIgnoreCase));
    }


    [Test]
    public void get_message_over_thirty_under_sixty_five_years()
    {
        //Given
        var givenUserOverThirtyUnderSixtyFive = UserMother.UserOverThirtyUnderSixtyFive();

        //When
        var message = home.Access(givenUserOverThirtyUnderSixtyFive);

        //Then
        Assert.IsTrue(string.Equals(message, "Consigue un descuento de 25€ en tu primer pedido",
            StringComparison.OrdinalIgnoreCase));
    }

    [Test]
    public void get_message_over_sixty_five_years()
    {
        //Given
        var givenUserOverSixtyFive = UserMother.UserOverSixtyFive();

        //When
        var message = home.Access(givenUserOverSixtyFive);

        //Then
        Assert.IsTrue(string.Equals(message, "Consigue un descuento de 30€ en tu primer pedido",
            StringComparison.OrdinalIgnoreCase));
    }
}Lenguaje del código: PHP (php)

UserMother.cs

    public class UserMother
    {
        private static Fixture _fixture = new Fixture();

        public static User UserUnderEighteen()
        {
            return _fixture.Build<User>()
                            .With(u => u.Age, 16)
                            .Create();
        }

        public static User UserOverEighteenUnderThirty()
        {
            return _fixture.Build<User>()
                            .With(u => u.Age, 29)
                            .Create();
        }

        public static User UserOverThirtyUnderSixtyFive()
        {
            return _fixture.Build<User>()
                            .With(u => u.Age, 46)
                            .Create();
        }

        public static User UserOverSixtyFive()
        {
            return _fixture.Build<User>()
                            .With(u => u.Age, 67)
                            .Create();
        }
    }Lenguaje del código: PHP (php)

Claramente, se puede ver como hemos combinado el Patrón Object Mother y Autofixture, y de este modo agrupamos la creación de los objetos que necesitamos, y como decíamos arriba, no perdemos la semántica de los Tests, y a la par podemos usar cómodamente AutoFixture.

Con este método abstraemos totalmente de los Tests de cómo estén creados los datos, y una vez se puede ver de forma sencilla cual es el dato.

De este modo cualquier modificación de los datos se hará de forma centralizada en la clase UserMother.cs, del mismo modo que se hacía antes, y como dejaremos que nuestros Tests se abstraigan totalmente de la lógica de creación de datos, reduciendo la complejidad en los mismos, y como siempre he dicho, quedan mas simples y se entienden mejor.

Me gustaría que pusieseis en comentarios cualquier otra técnica o patrón que hayáis usado para la creación de datos en los Tests, o cualquier técnica que queráis compartir.

¿Os ha gustado esta combinación?

Saludos, y como siempre, gracias por leerme!!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *