Sempre que escrevemos um software em que temos as nossas entidades, no momento de fazer os testes sempre precisamos criar alguns dados falsos para validar a lógica implementada.

Quem nunca criou várias dessas entidades manualmente e, como a maioria das pessoas desenvolvedoras, sofreu para inventar nomes e valores aleatórios para esses objetos de teste? Você que está lendo este artigo provavelmente já fez algo desse tipo:

[
  {
    "userId": 1,
    "id": 1,
    "title": "delectus aut autem",
    "completed": false
  },
  {
    "userId": 1,
    "id": 2,
    "title": "quis ut nam facilis et officia qui",
    "completed": false
  },
  {
    "userId": 1,
    "id": 3,
    "title": "fugiat veniam minus",
    "completed": false
  },

    ...

  {
    "userId": 1,
    "id": 41,
    "title": "et porro tempora",
    "completed": true
  },
  {
    "userId": 1,
    "id": 42,
    "title": "laboriosam mollitia et enim quasi adipisci quia provident illum",
    "completed": false
  },
]

Essa abordagem é uma boa solução quando precisamos de apenas um item nos nossos testes, mas quando surge a necessidade de criarmos vários, além de ser um exercício de criatividade para inventar tanta informação, pode ser bem trabalhoso ajustar essa lista caso alguma coisa mude nessa entidade. Isso nos forçaria a fazer o ajuste em todos os itens da lista.

Outra possível desvantagem nessa abordagem é que nosso teste pode ficar enviesado com dados que preenchemos manualmente. É aí que entram as ferramentas de geração de fakes para auxiliar nessa tarefa, na minha humilde opinião, chata pra caramba.

Automatizando a criação dos objetos para teste

Vou apresentar aqui uma ferramenta bem simples chamada FluentBuilder (inclusive, se estiver estudando generics do Typescript, este projeto é um ótimo exemplo).

Como o FluentBuilder foi feito com Typescript, podemos aproveitar toda a comodidade de utilizar o intellisense para ajudar a entender como utilizá-lo. Mas vamos ver como isso funciona.

Seguindo o exemplo do começo do artigo, imagine que temos a seguinte interface:

interface Todo {
    userId: number,
    id: number,
    title: string,
    completed: boolean
}

Com a interface definida, podemos criar o nosso builder, que irá gerar os nossos objetos fake:

class TodoBuilder extends Builder<Todo> {
  constructor() {
    super();
    this.ruleFor("idUser", (faker) => faker.random.number());
    this.ruleFor("id", (faker) => faker.random.number());
    this.ruleFor("title", (faker) => faker.random.words());
    this.ruleFor("completed", () => false);
  }

Para criar uma classe capaz de gerar os nossos fakes, precisamos somente estender a classe Builder, passando à interface que será usada para gerar os nossos objetos:

Fakes no Typescript com FluentBuilder

Classe extendendo o Builder

Note que o intellisense consegue inclusive listar as propriedades da interface e, com isso, conseguimos escolher para qual delas vamos criar a regra para gerar um valor aleatório.

Uma vez que temos o nosso builder devidamente configurado, podemos utilizá-lo para gerar a nossa lista de objetos:

describe('Todos', () => {
    test('Deve ...', () => {
        const todos = new TodoBuilder().generate(41)
    })
})

O FluentBuilder utiliza o Faker.js para gerar as informações aleatórias, que é uma instância dele que é passada no ruleFor. Caso queira apenas uma instância, ao invés de uma lista é só chamar o método generate sem passar uma quantidade:

describe('Todos', () => {
    test('Deve ...', () => {
        const todo = new TodoBuilder().generate()
    })
})

E com a nossa lista de objetos pronta, podemos utilizá-los para fazer os nossos testes:

import axios from 'axios'

jest.mock('axios');
const mockedAxios = axios as jest.Mocked<typeof axios>;

describe('Todos', () => {
    test('Deve ...', () => {
        const todos = new TodoBuilder().generate(5)

    mockedAxios.get.mockResolvedValue({
      data: todos,
    });
    })
})

Conclusão

Ferramentas como o FluentBuilder não são itens obrigatórios para que nossos projetos atinjam seus objetivos, mas com certeza facilitam a nossa vida e deixam o código muito mais fácil de entender.

Referências

Lucas Teles – Fluentbuilder 

Design Patterns – Builder 

Design Patterns – Builder com Typescript 

Fernando Okuma

Desenvolvedor de aplicações de alto e baixo nível e aspirante a agilista.