FSCheck: Gerando valores customizados para seu teste de propriedade
Tags: bibliotecas, testes, csharp, fscheck
Published: 2022-02-09 01:57:31

---
title: FSCheck: Gerando valores customizados para seu teste de propriedade
published: true
date: 2021-02-11 17:33:15 UTC
tags: Bibliotecas,Testes,csharp,fscheck
canonical_url: http://high5devs.com/2021/02/fscheck-gerando-valores-customizados-para-seu-teste-de-propriedade/
---

Em um outro [post](http://high5devs.com/2020/05/fscheck-mudando-sua-visao-sobre-testes/), falamos um pouco sobre a utilização do FSCheck para criação de testes de propriedade usando C#. Mostrei os primeiros passos com o FSCheck, e a criação de testes de propriedade bem simples onde nosso teste dependia de um valor _uint p_ara representar uma porcentagem, porém esse tipo de valor pode ser maior do que 100, o que no nosso caso se encaixa muito bem dado que nossa porcentagem seria somente de 0 a 100.

Nesse post iremos nos aprofundar um pouco mais na criação de parâmetros customizáveis, limitando os valores, criando alguns mais específicos e descritivos.

* * *

## Contexto

No primeiro post que fiz sobre o FSCheck mostrei um contexto de uma aplicação de _FlashCards_ onde testávamos se um cartão tinha sua porcentagem de dificuldade diminuída caso o usuário acertasse a reposta ou se aumentava a dificuldade caso o usuário errasse. O código do nosso exemplo é esse aqui:

```

[Property]
public Property DeveDiminuirDificuldadeQuandoAcertarAResposta(int porcentagem)
{
 var calculadora = new CalculadoraDeDificuldade();
 var cartão = new Cartão("qlqr pergunta", porcentagem);

 var novoCartão = calculadora.AjustaDificuldade(cartão, true);

 return (novoCartão.Porcentagem < porcentagem).ToProperty();
}

```

A questão com esse teste é que o valor de porcentagem está variando entre todos os possíveis para uma variável do tipo _int_, e a nossa propriedade só é válida quando o valor da porcentagem for entre 0 e 100. O FsCheck possui o método _When_ que faz exatamente isso, portanto podemos alterar a criação da nossa propriedade para que fique assim:

```
 
return (novoCartão.Porcentagem < porcentagem)
         .ToProperty()
         .When(porcentagem != 0 && porcentagem < 100); 

```

Utilizando o método _When_  conseguimos limitar o valor do parâmetro porcentagem que será válido para a nossa Propriedade, porém agora todo teste que dependa desse valor teremos que adicionar esse código. O que precisamos é que o FSCheck saiba gerar corretamente os valores, e para isso ele disponibiliza uma maneira de criar os nossos próprios geradores de valores.

## Gerando valores customizáveis

Para criar esse valores customizaveis iremos criar uma classe para agrupar os geradores, e esses geradores serão métodos estáticos que retornam um Arbitrary do valor que quer gerar.  
O nome do método podemos colocar algo que deixe explícito o retorno.  
No nosso caso o tipo que usamos é int, iremos criar um método estatico que irá retornar um Arbitrary de int e iremos dar o nome de Porcentagem.

```

    public class Tipos
    {
        public static Arbitrary<int> Porcentagem() =>
            Arb.Default.Int32().Generator.
                Where(x => x > 0 && x <= 100).ToArbitrary();
    }

```

Olhando a implementação acima veja que utilizamos o próprio gerador de int da biblioteca _Arb.Default.Int32().Generator_ e depois usamos um Where para filtrar o intervalo de valores que queremos. E para retornar um Arbitrary basta chamar o método ToArbitrary.  
Agora que criamos esse gerador, precisamos fazer indicar para o nosso teste que deve utilizar essa classe como fonte. Conseguimos fazer isso apenas alterando o atributo Property:

```

[Property(Arbitrary = new[] {typeof(Tipos)})]

```

Com isso quando o nosso teste solicita uma entrada to tipo int, ele acha o nosso gerador e chama ele ao invés do padrão, com isso nosso código não precisa mais lidar com o tratamento do valor e podemos remover o When que tínhamos colocado.

Olhando nosso código, utilizamos a porcentagem para criar nosso objeto Cartão e usamos ele para fazer o teste. E se, ao invés de receber a porcentagem, nós recebessemos um objeto de Cartão já pronto?

## Criando nosso Cartão

Para criar um novo gerador, precisamos alterar nossa classe Tipos, e adicionar agora um novo método que retorne um Arbitrary de Cartão. Nele podemos utilizar o gerador de Porcentagem que criamos e mapear para um Cartão. Veja como fica a implementação:

```

public static Arbitrary<Cartão> Cartão() =>
  Porcentagem().Generator
    .Select(porcentagem => new Cartão(Arb.Default.String()
                                                 .Generator
                                                 .Sample(20, 1)
                                                 .Single(),
                                      porcentagem))
    .ToArbitrary();

```

Veja que estamos mapeando uma porcentagem para o nosso Cartão, e utilizamos outro gerador padrão do FSCheck para construir a descrição do cartão de maneira automática também. Agora basta alterar nosso teste para receber um Cartão

```

        [Property(Arbitrary = new[] {typeof(Tipos)})]
        public Property DeveDiminuirDificuldadeQuandoAcertarAResposta3(Cartão cartão)
        {
          var calculadora = new CalculadoraDeDificuldade();

          var novoCartão = calculadora.AjustaDificuldade(cartão, true);

          return (novoCartão.Porcentagem < cartão.Porcentagem).ToProperty();
        }

```

Com isso conseguimos construir qualquer objeto nosso com as restrições que precisamos para determinada propriedade, e deixar nosso teste simples e descritivo.  
Podemos também criar classes que representem estados dos nossos objetos, como por exemplo um _ **CartãoComPorcentagemAcimaDe80** _ que estende o _Cartão_. Dá para viajar nisso, mas falaremos disso em outro post.

Se quiser dar uma olhada no código, ele está no meu github: [fscheck-examples](https://github.com/afucher/fscheck-examples)

* * *

Eai, o que achou da utilização de geradores customizáveis? Tem dúvidas? Já usou?  
Deixe um comentário ?

Abraços

 

_Imagem usada no post [Orsolya Vékony](https://unsplash.com/@vekonyorsi?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) em_ [_Unsplash_](https://unsplash.com/s/photos/hammer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

O post [FSCheck: Gerando valores customizados para seu teste de propriedade](http://high5devs.com/2021/02/fscheck-gerando-valores-customizados-para-seu-teste-de-propriedade/) apareceu primeiro em [High5Devs](http://high5devs.com).