FactoryBot: usando build_stubbed

Dicas - 22/Mar/2021 - por André Kanamura

Anteriormente falamos sobre os métodos build e attributes_for do FactoryBot para nos ajudar a prototipar instâncias de models de nossas aplicações Ruby On Rails e realizar nossos testes. Neste artigo vamos falar um pouco sobre o método build_stubbed e como ele pode ser usado para deixar seu conjunto de testes mais rápido.

Da mesma maneira que os métodos build e create, o build_stubbed pode ser usado para criar instâncias de models com seus atributos. Essas instâncias vão ter todos os seus atributos e associações, e vão responder aos métodos como objetos comuns, mas a diferença é que não são criados registros no banco de dados e validações não são disparadas. Por essa razão, eles são muito mais rápidos.

Considere, por exemplo, as factories de user e address:

class User
  def initialize(full_name:, address:)
    @full_name = full_name
    @address = address
  end

  def full_profile?
    @address.present? && !full_name.empty?
  end
end

class Address
  def initialize(zipcode:, street:, city:, country:, state:, number:)
    @zipcode = zipcode
    @street = street
    @city = city
    @country = country
    @state = state
    @number = number
  end
end

Quando usamos o método build_stubbed para criar instâncias dessas classes nos testes, o banco de dados não é acessado e podemos fazer testes como:

describe User do
  let(:address) { build_stubbed(:address) }
  subject(:user) { User.new(full_name: 'Apolonio S.', address: address) }

  context '#full_profile?' do
    it 'should be true if user has full name and address' do
      expect(user.full_profile?).to eq true
    end
  end
end

No lugar de criar dezenas de registros em banco, não é necessário criar nenhum e isso torna os testes muito mais rápidos. Quando os modelos do projeto possuem muitas outras dependências de outros modelos, podemos evitar que todos esses dados sejam criados em banco usando o build_stubbed. Isso é especialmente interessante quando o conjunto de testes da aplicação é extenso. Imagine mais de 1000 testes criando dados em banco e acessando a cada cenário. O tempo economizado seria bem considerável.

Naturalmente, essa estratégia não funciona em qualquer situação. O build_stubbed é interessante em casos em que realmente não nos importamos em como esse objeto é salvo em banco ou como os dados são apresentados.

Referências e outras leituras

Foto de perfil do autor
André Kanamura

Dev na Campus Code