Skip to content

Latest commit

 

History

History
131 lines (94 loc) · 4.1 KB

File metadata and controls

131 lines (94 loc) · 4.1 KB

5 - FactoryBot e Faker

Por que usar factories?

Criar dados de teste manualmente é repetitivo e frágil. Se o modelo mudar (ex: um novo campo obrigatório), precisamos atualizar cada lugar que cria dados manualmente.

Com FactoryBot, definimos os dados de teste em um único lugar. Os cenários apenas pedem build(:user) e recebem um objeto pronto - sem se preocupar com os detalhes de cada campo.

Model

O model define a estrutura dos dados. Neste projeto usamos Struct pela simplicidade:

# lib/models/users_model.rb

UsersModel = Struct.new(:nome, :email, :password, :administrador) do
  def user_hash
    to_h
  end
end

to_h converte o Struct em Hash com chaves Symbol, e user_hash expõe esse comportamento com um nome mais expressivo.

user = UsersModel.new('Ana', 'ana@example.com', 'senha123', 'false')
user.user_hash
# => { nome: "Ana", email: "ana@example.com", password: "senha123", administrador: "false" }

Quando chamamos .to_json em seguida, as chaves Symbol são convertidas para String automaticamente:

user.user_hash.to_json
# => '{"nome":"Ana","email":"ana@example.com","password":"senha123","administrador":"false"}'

Factory

A factory define como criar instâncias do model com dados gerados automaticamente:

# lib/factories/users_factory.rb

require 'faker'
require_relative '../models/users_model'

FactoryBot.define do
  factory :user, class: UsersModel do
    nome          { Faker::Name.name }
    email         { Faker::Internet.email(domain: 'example.com') }
    password      { Faker::Internet.password(min_length: 6, max_length: 12, mix_case: true) }
    administrador { 'false' }
  end
end

Cada campo recebe um bloco { } que é avaliado na hora da criação - garantindo dados únicos e aleatórios a cada chamada.

Faker

O Faker gera dados falsos e realistas. Alguns exemplos úteis para testes de API:

Faker::Name.name                              # => "Carlos Silva"
Faker::Internet.email(domain: 'example.com')  # => "carlos.silva@example.com"
Faker::Internet.password(min_length: 6)       # => "sK9#mLp"
Faker::Internet.username                      # => "carlos_silva"
Faker::Number.number(digits: 5)               # => "48291"
Faker::Lorem.sentence                         # => "Lorem ipsum dolor sit amet."

Atenção: Faker::Internet.email sem argumentos gera TLDs reservados como .test e .example. A ServeRest (e muitas APIs) rejeita esses emails como inválidos. Sempre use domain: 'example.com' ou similar.

Usando a factory nos steps

O World(FactoryBot::Syntax::Methods) no env.rb injeta o método build diretamente nos steps:

# Cria o objeto sem salvar em banco (não tem banco, mas o nome vem dessa convenção)
user = build(:user)

# Acessa os campos
user.nome       # => "Carlos Silva"
user.email      # => "carlos.silva@example.com"

# Converte para Hash para enviar como corpo da requisição
user.user_hash
# => { nome: "Carlos Silva", email: "carlos.silva@example.com", ... }

Exemplo completo no step

Dado('que existe um usuário cadastrado') do
  @payload_user = build(:user).user_hash
  response = users_service.post_user(@payload_user)
  @created_user_id = response.parsed_response['_id']
end

Sobrescrevendo atributos

É possível sobrescrever qualquer campo da factory na hora da criação:

# Criar um usuário administrador
admin = build(:user, administrador: 'true')

# Criar com email fixo (útil para testar duplicata)
user = build(:user, email: 'fixo@example.com')

Resumo do fluxo

build(:user)
  └── FactoryBot executa o bloco de cada campo
        ├── nome:          Faker::Name.name          => "Ana Lima"
        ├── email:         Faker::Internet.email...  => "ana@example.com"
        ├── password:      Faker::Internet.password  => "Xk3#mP"
        └── administrador: 'false'

  └── Retorna UsersModel.new("Ana Lima", "ana@example.com", "Xk3#mP", "false")

.user_hash
  └── Retorna { nome: "Ana Lima", email: "ana@example.com", ... }

.to_json
  └── '{"nome":"Ana Lima","email":"ana@example.com",...}'