Criando dados fake para testes em .Net
Tags: csharp, dotnet, braziliandevs, testing
Published: 2021-05-12 11:24:29

Olá, hoje vou apresentar uma biblioteca muito interessante capaz de gerar dados aleatórios muito precisos na nossa língua portuguesa (e outras línguas também) chamada **Bogus**.

## Problema a ser solucionado

Frequentemente nos vemos diante de um teste ou criação de uma POC (proof of concept) onde necessitamos de uma massa de dados para validar nosso código, esses dados necessitam ser o mais parecido possível com o que esperamos para não deixarmos passar nenhum detalhe em nossas validações. Muitas vezes optamos por criar esses dados na mão, mas dependendo da quantidade necessária levamos muito tempo criando, as vezes até duplicando dados.

Nesse contexto a biblioteca Bogus nos auxilia muito, ela é capaz de gerar uma massa de dados do tamanho que você necessita, de forma rápida sem repetir nenhum registro, com suporte a diferentes línguas e muitas opções de dados para que o teste fique o mais real possível.

## Demonstração

Para demonstrar o uso da biblioteca, iremos criar um projeto console em .Net e adicionar a biblioteca através do gerenciador de pacotes nuget ou da execução do comando:

```csharp
dotnet add package Bogus
``` 

Vamos também criar nossa classe `Pessoa` (mais clássico impossível hahahaha), que será utilizada para gerar nossa massa de dados.

```csharp
public class Pessoa
{
	public int Id { get; set; }
	public string Nome { get; set; }
	public string Email { get; set; }
	public DateTime DataNascimento { get; set; }
	public string Telefone { get; set; }
}
```

Pronto, vamos agora começar a usar a biblioteca para gerar alguns dados. Dentro da classe `Program` da nossa aplicação console iremos configurar para ser gerado um objeto Pessoa.

```csharp
Pessoa pessoa = new Faker<Pessoa>("pt_BR")
	.RuleFor(x => x.Id, f => f.Random.Int(1))
	.RuleFor(x => x.Nome, f => f.Name.FullName())
	.RuleFor(x => x.Email, (f, u) => f.Internet.Email(u.Nome))
	.RuleFor(x => x.DataNascimento, f => f.Date.Past(50))
	.RuleFor(x => x.Telefone, f => f.Phone.PhoneNumberFormat())
	.Generate();

Console.WriteLine(JsonConvert.SerializeObject(pessoa, Formatting.Indented));
```

Se você já utilizou a biblioteca `FluentValidation` deve estar reconhecendo a forma de configurar, é praticamente igual.

Olhando o código podemos ver que estamos instanciando a classe `Faker` passando Pessoa como tipo genérico e setando a língua para português do Brasil, isso ajuda muito a termos dados mais precisos.

A partir dai criamos uma regra para cada propriedade da classe Pessoa.

```csharp
.RuleFor(x => x.Id, f => f.Random.Int(1))
```
Setando para a propriedade `Id` um valor aleatório inteiro sendo o valor mínimo 1.

```csharp
.RuleFor(x => x.Nome, f => f.Name.FullName())
```
Setando para a propriedade `Nome` um nome completo aleatório. 

Veja no exemplo abaixo que a biblioteca é tão legal que podemos até especificar se queremos um nome do sexo masculino ou feminino.
```csharp
.RuleFor(x => x.Nome, f => f.Name.FullName(Bogus.DataSets.Name.Gender.Male))
```

```csharp
.RuleFor(x => x.Email, (f, u) => f.Internet.Email(u.Nome))
```
Setando para a propriedade `Email` um email aleatório baseado no nome gerado anteriormente.

```csharp
.RuleFor(x => x.DataNascimento, f => f.Date.Past(50))
```
Setando para a propriedade `DataNascimento` uma data baseada nos últimos 50 anos.

```csharp
.RuleFor(x => x.Telefone, f => f.Phone.PhoneNumberFormat())
```
Setando para a propriedade `Telefone` um número já formatado no padrão utilizado aqui no Brasil.

Rodando a aplicação teremos no console o resultado:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bc0lvk3d3yy9kpfni3w8.PNG)

Como podemos ver nos exemplos acima são muitas opções de customização para os dados fazendo com que o resultado seja muito próximo de um dado real.

## Criando uma grande quantidade de dados

Olhando novamente o exemplo anterior, quem faz de fato o objeto ser criado é o método `Generate()`, sendo assim se você precisar de 500 registros, basta você setar `Generate(500)` que ele irá gerar 500 registros sendo nenhum deles repetido, segue um exemplo.

```csharp
List<Pessoa> pessoaLista = new Faker<Pessoa>("pt_BR")
	.RuleFor(x => x.Id, f => f.Random.Int(1,100))
	.RuleFor(x => x.Nome, f => f.Name.FullName())
	.RuleFor(x => x.Email, (f, u) => f.Internet.Email(u.Nome))
	.RuleFor(x => x.DataNascimento, f => f.Date.Between(Convert.ToDateTime("01/01/1990"), Convert.ToDateTime("01/01/2000")))
	.RuleFor(x => x.Telefone, f => f.Phone.PhoneNumberFormat())
	.Generate(500);
```

## Projeto de exemplo
Caso tenha ficado ainda alguma dúvida no código, você pode ver o exemplo que eu criei nesse repositório do [Github](https://github.com/marcosbelorio/fake-data-example).

Se gostou utilize os botões do lado esquerdo para que eu possa saber. Caso tenha alguma dúvida, sugestão ou crítica, deixe um comentário logo abaixo.

Muito obrigado!