Lors de l'écriture d'un test pour le modèle User dans Rspec
Dans un test pour confirmer l'unicité de l'email
Si vous utilisez FactoryBot.create ()
, le même test sera répété plusieurs fois par la suite.
L'erreur suivante s'affiche dans le deuxième test et les suivants
ActiveRecord::RecordInvalid:
Validation failed: Email has already been taken
Il semble que la base de données ne soit pas annulée pour chaque test.
Les paramètres suivants ont été définis dans spec / rails_helper.rb
(par défaut)
spec/rails_helper.rb
config.use_transactional_fixtures = true
rails db:migrate:reset RAILS_ENV=test
Après cela, le test n'a réussi qu'une seule fois
spec/factories/users.rb
FactoryBot.define do
factory :user, class: User do
username {"test_user"}
email {"[email protected]"}
password {"password"}
password_confirmation {"password"}
end
factory :existed_user, class: User do
username { "existed_user" }
email { "[email protected]" }
password { "password" }
password_confirmation { "password" }
end
end
spec/models/user_spec.rb
subject(:user) { FactoryBot.build(:user, email: email) }
context "Lorsque les e-mails sont dupliqués" do
existed_user = User.find_by(username: "existed_user") || FactoryBot.create(:existed_user)
let(:email) { existed_user.email }
it { is_expected.to be_invalid }
end
User.find_by(username: "existed_user") || FactoryBot.create(:existed_user)
Seulement lorsque cela est nécessaire dans la partie decreate
Réécrit pour faire
Il semble y avoir une solution plus essentielle utilisant des gemmes ou autre chose, Jusqu'à présent, le problème peut être évité par la méthode de 2).
En outre, la définition séquentielle de l'usine a été introduite dans plusieurs articles. Seulement 5 choses à retenir lors de l'utilisation de FactoryBot-Qiita
Aussi, FactoryBot.create (: exist_user)
et
Lorsque vous faites FactoryBot.build (: exist_user)
Vous devez spécifier class: User
dans FactoryBot.define
A rencontré l'erreur suivante
NameError: uninitialized constant ExistedUser
Puisque FactoryBot.create (: user)
et FactoryBot.build (: user)
sont bien
Il semble qu'il s'agit de la classe User sans autorisation
Premier RSpec Résultat J'ai écrit un test du modèle utilisateur comme suit
require 'rails_helper'
describe User do
describe "#create" do
it "username, email, password,Vous pouvez vous inscrire si la confirmation du mot de passe existe" do
user = FactoryBot.build(:user)
expect(user).to be_valid
end
describe "username" do
subject(:user) { FactoryBot.build(:user, username: username) }
context "Impossible de s'inscrire si le nom d'utilisateur n'existe pas" do
let(:username) { "" }
it { is_expected.to be_invalid }
end
context "Peut être enregistré lorsque le nom d'utilisateur comporte 12 caractères" do
let(:username) { "a"*12 }
it { is_expected.to be_valid }
end
context "Ne peut pas être enregistré si le nom d'utilisateur comporte 13 caractères" do
let(:username) { "a"*13 }
it { is_expected.to be_invalid }
end
context "Si le nom d'utilisateur est dupliqué" do
existed_user = User.find_by(username: "existed_user") || FactoryBot.create(:existed_user)
let(:username) { existed_user.username }
end
end
describe "email" do
subject(:user) { FactoryBot.build(:user, email: email) }
context "Si l'e-mail n'existe pas" do
let(:email) { "" }
it { is_expected.to be_invalid }
end
context "Lorsque les e-mails sont dupliqués" do
existed_user = User.find_by(username: "existed_user") || FactoryBot.create(:existed_user)
let(:email) { existed_user.email }
it { is_expected.to be_invalid }
end
end
describe "password" do
subject(:user) { FactoryBot.build(:user, password: password, password_confirmation: password_confirmation) }
context "Si le mot de passe n'existe pas" do
let(:password) { "" }
let(:password_confirmation) { "password" }
it { is_expected.to be_invalid }
end
context "Si le mot de passe existe mais que la confirmation du mot de passe n'existe pas" do
let(:password) { "passowrd" }
let(:password_confirmation) { "" }
it { is_expected.to be_invalid }
end
context "le mot de passe est un mot de passe_S'il ne correspond pas à la confirmation" do
let(:password) { "password_a" }
let(:password_confirmation) { "password_b" }
it { is_expected.to be_invalid }
end
context "Si le mot de passe comporte 7 caractères" do
let(:password) { "a"*7 }
let(:password_confirmation) { "a"*7 }
it { is_expected.to be_invalid }
end
context "Si le mot de passe comporte 8 caractères" do
let(:password) { "a"*8 }
let(:password_confirmation) { "a"*8 }
it { is_expected.to be_valid }
end
end
end
end