FactoryBot: usando build e attributes_for

Dicas - 28/Fev/2021 - por André Kanamura

O FactoryBot é uma ferramenta muito utilizada em desenvolvimento de projetos Ruby on Rails por permitir prototipar com facilidade instâncias de models da sua aplicação dentro do ambiente de testes. Além de poder ser utilizado para popular seu banco de dados, podemos criar objetos não salvos e atributos para models usando os métodos build e attributes_for. Vamos considerar a factory a seguir:

# encoding: UTF-8
FactoryBot.define do
  factory :address do
    zipcode { '00000-000' }
    street  { 'R. Campus Code' }
    city    { 'São Paulo' }
    country { 'BR' }
    state   { 'SP' }
    number  { '555' }
    neighborhood { 'Vila Matilde' }
  end
end

O model Address precisa dos atributos CEP, rua, cidade, país, estado, número e bairro para ser registrado no formulário de criação e nosso teste ficaria mais ou menos assim:

feature 'Usuário cadastra endereço' do
  scenario `com sucesso` do
    address = build(:adress)

    visit new_address_path
    fill_in ‘CEP’, with: address.zipcode
    fill_in ‘Rua’, with: address.street
    fill_in ‘Cidade’, with: address.city
    fill_in ‘País’, with: address.country
    fill_in ‘Estado’, with: address.state
    fill_in ‘Número’, with: address.number
    fill_in ‘Bairro’, with: address.neighborhood
    click_on 'Registrar'

    expect(page).to have_content('Conta criada com sucesso')
    expect(page).to have_content(address.street)
    expect(page).to have_content(address.zipcode)
  end
end

Dessa forma, a factory dá conta de criar os dados pra gente e podemos nos preocupar com outros aspectos do teste que podem ser mais importantes. A mesma estrutura poderia ser usada para "buildar" um objeto com um atributo específico, por exemplo:

  build(:address, street: 'R. da Glória')

  # ou

  build(:address, country: nil)

Nesse caso, poderia ser utilizado para testar validações de presença de atributos antes de salvar o objeto, por exemplo.

Esse método é bastante útil em testes unitários em que queremos verificar o funcionamento de determinadas ações que salvam objetos em banco, mas não queremos nos preocupar em especificar cada um dos atributos do model.

Outra maneira de obter dados semelhantes é usando o attributes_for. Esse método vai criar uma Hash com os atributos especificados na factory. Por exemplo:

attributes_for(:address)
#=> { zipcode: '00000-000', street: 'R. Campus Code', city: 'São Paulo', country: 'BR',   state: 'SP', number: '555', neighborhood: 'Vila Matilde' }

A diferença é que os dados são criados em forma de Hash em vez de uma instância de um model.

O FactoryBot é uma ferramenta super interessante e oferece muitas funcionalidades que ajudam bastante na estruturação dos testes das nossas aplicações. Recomendamos a leitura dos conteúdos listados abaixo para aproveitar ainda mais o FactoryBot.

Outras leituras:

Foto de perfil do autor
André Kanamura

Dev na Campus Code