[RUBY] [RSpec] Maîtrisons Factory Bot

Clé de base FactoryBot

bin/rails g factory_bot:model user

Un fichier qui crée des données avec FactoryBot est généré comme indiqué dans. Cette fois, je pense que le fichier suivant sera généré dans spec / factories / users.rb.

spec/factories/users.rb


FactoryBot.define do
  factory :user do
  end
end

J'emballerai les données que je veux créer dans ceci.

spec/factories/users.rb


FactoryBot.define do
  factory :user do
    name {"Sato"}
    age {20}
    height {170}
  end
end

Utilisons-le réellement.

spec/models/user.rb


require 'rails_helper'

RSpec.describe User, type: :model do
  it "is valid with a name, age and height" do
    expect(FactoryBot.build(:user)).to be_valid
  end
end

Vous pouvez l'écrire de manière concise comme ceci. Au fait, si vous n'utilisez pas FactoryBot, ce sera comme suit.

spec/models/user.rb


require 'rails_helper'

RSpec.describe User, type: :model do
  it "is valid with a name, age and height" do
    user = User.new(
      name: "Sato",
      age: 20,
      height: 170,
    )
    expect(user).to be_valid
  end
end

Cela ressemblera à ceci et le nombre de lignes augmentera.

Bien qu'il soit plus facile à lire, le contenu des données est masqué dans le FactoryBot, alors choisissez de l'utiliser ou non en fonction du cas d'utilisation.

passer outre

Vous pouvez remplacer les données du fichier dans lequel vous écrivez les spécifications.

spec/models/user.rb


require 'rails_helper'

RSpec.describe User, type: :model do
  it "is invalid without a name" do
    user = FactoryBot.build(:user, name: nil)
    user.vaild?
    expect(user.errors[:name]).to include("can't be blank")
  end
end

Remplacez le contenu de FactoryBot et remplacez «nom» par «nil».

Utilisez des séquences pour créer des données uniques

Par exemple, «hydromel» doit être une valeur unique. Cependant, si vous utilisez FactoryBot tel quel, la même valeur sera saisie à chaque fois, elle sera donc interceptée lors de la validation. (Involontairement.)

Une «séquence» est fournie pour résoudre ce problème.

spec/factories/users.rb


FactoryBot.define do
  factory :user do
    name {"Sato"}
    age {20}
    height {170}
    #Une séquence est utilisée pour le courrier électronique.
    sequence(:email) {|n| "test#{n}@example.com"}
  end
end

Cela vous permettra de toujours saisir une valeur unique telle que «test1 @ exemple.com», «test2 @ exemple.com» chaque fois qu'un nouvel utilisateur est créé.

Rendre l'usine plus diversifiée

Par exemple, supposons que vous souhaitiez tester une personne âgée ou une personne de grande taille. Vous pouvez absorber les petits problèmes en usine. Il existe deux méthodes principales.

Utiliser l'héritage

spec/factories/users.rb


FactoryBot.define do
  factory :user do
    name {"Sato"}
    age {20}
    height {170}
    sequence(:email) {|n| "test#{n}@example.com"}

    #Données pour les personnes âgées
    factory :senior do
      age {75}
    end
  
    #Données pour les personnes de grande taille
    factory :tall do
      height {190}
    end
  end
end

Il peut être utilisé comme FactoryBot.build (: user ,: senior) ou FactoryBot.build (: user ,: tall).

Utilisez le trait.

J'aime mieux celui-ci. La raison en est qu'il peut être raccourci en l'écrivant dans ** FactoryBot **, ** vous pouvez voir ce qui est "différent" **. Jetons un coup d'oeil quand même!

spec/factories/users.rb


FactoryBot.define do
  factory :user do
    name {"Sato"}
    age {20}
    height {170}
    sequence(:email) {|n| "test#{n}@example.com"}

    
    trait :senior do
      age {75}
    end
  
    trait :tall do
      height {190}
    end
  end
end

Il peut être appelé en écrivant comme FactoryBot.build (: user ,: senior).

En faisant cela, les ** caractéristiques ** des données sont clairement affichées, donc elles sont très lisibles, n'est-ce pas?

Rappeler

FactoryBot peut également exprimer des mouvements dynamiques. Voir le code ci-dessous.

spec/factories/users.rb


FactoryBot.define do
  factory :user do
    name {"Sato"}
    age {20}
    height {170}
    sequence(:email) {|n| "test#{n}@example.com"}

    trait :with_tasks do
      after(:create) { |user| create_list(:task, 5, user: user) }
    end
  end
end

Vous pouvez créer des tâches liées à l'utilisateur en faisant FactoryBot.build (: user ,: with_tasks).

Recommended Posts

[RSpec] Maîtrisons Factory Bot
[RSpec] Utilisons FactoryBot [Rails]
[rails] Faisons un test unitaire avec Rspec!