Pour le moment, j'ai pu confirmer que la création et la lecture fonctionnent la dernière fois. De là, suivez cette procédure
Dans cet article, je vais implémenter 1 et 2 pour le moment, et après 3. je vais passer aux articles suivants et suivants.
Écrire un document Excluez l'erreur telle qu'elle apparaît dans le fichier de migration.
.rubocop.yml peut être exclu de cette manière, mais si vous excluez ce dont vous avez besoin à l'origine, cela brisera le sens de l'observation des normes de codage en premier lieu, alors discutons-en fermement lors de l'ajout dans le développement d'équipe. ..
diff:.rubocop.yml
+ #Documentation
+ Style/Documentation:
+ Exclude:
+ - "db/migrate/**/*"
...
Comme Test Driven Development (TDD), le premier est le test de Red. Puisque la validation n'est pas implémentée, je vais faire quelque chose qui sera rouge même si j'écris un test et l'exécute.
Je vais l'écrire dans une coche Rails normale sans utiliser une seule fois factory_bot.
spec/models/post_spec.rb
# frozen_string_literal: true
require "rails_helper"
RSpec.describe Post, type: :model do
describe "subject" do
context "Lorsque vide" do
it "Devenir invalide" do
post = Post.new(subject: "", body: "fuga")
expect(post).not_to be_valid
end
end
end
end
Donc, le code ci-dessus teste que "il devient invalide lorsque le sujet est vide". Mais jusqu'à présent, je n'ai pas validé le sujet du modèle de publication, donc le message est valide et le test "invalide" échouera.
$ rspec spec/models/post_spec.rb
...
Finished in 0.07805 seconds (files took 3.53 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/models/post_spec.rb:8 #Non valide lorsque le sujet du message est vide
ec2-user:~/environment/bbs (master) $ rspec
Essayons de nous inscrire même si le sujet est vide.
$ rails c
[1] pry(main)> Post.create!(subject: "", body: "hoge")
(0.1ms) BEGIN
Post Create (2.5ms) INSERT INTO "posts" ("subject", "body", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["subject", ""], ["body", "hoge"], ["created_at", "2020-09-06 01:07:52.628768"], ["updated_at", "2020-09-06 01:07:52.628768"]]
(0.9ms) COMMIT
=> #<Post:0x0000000005760700
id: 2,
subject: "",
body: "hoge",
created_at: Sun, 06 Sep 2020 01:07:52 UTC +00:00,
updated_at: Sun, 06 Sep 2020 01:07:52 UTC +00:00>
Vous l'avez sauvegardé.
Au fait, sans utiliser de description ni de contexte
spec/models/post_spec.rb
# frozen_string_literal: true
require "rails_helper"
RSpec.describe Post, type: :model do
it "Invalide lorsque le sujet est vide" do
post = Post.new(subject: "", body: "fuga")
expect(post).not_to be_valid
end
end
Le comportement du code de test est presque le même. C'est parce que vous pouvez tester en écrivant expect dans le bloc it. Cependant, il devient difficile à comprendre lors de la description de la même colonne et des mêmes conditions de validation par regroupement, il est donc fondamentalement recommandé de décrire en imbriquant la description et le contexte.
app/models/post.rb
class Post < ApplicationRecord
+ validates :subject, presence: true
end
Vous ne pouvez plus vous inscrire avec vrai ou vide pour la présence de la colonne sujet.
Essayons.
$ rails c
[1] pry(main)> Post.create!(subject: "", body: "hoge")
ActiveRecord::RecordInvalid: Validation failed: Subject can't be blank
from /home/ec2-user/.rvm/gems/ruby-2.7.1/gems/activerecord-6.0.3.2/lib/active_record/validations.rb:80:in `raise_validation_error'
Je ne peux pas m'inscrire.
$ rspec ./spec/models/post_spec.rb
...
Finished in 0.05053 seconds (files took 1.63 seconds to load)
1 example, 0 failures
Le test a également réussi.
Comme ce serait un problème si le nombre de caractères pouvait être enregistré indéfiniment, nous ajouterons une limite. C'est aussi le premier test. J'écrirai un test avec un plan pour ajouter la validation qu'il est OK s'il est de 30 caractères ou moins et NG s'il est de 31 caractères ou plus.
spec/models/post_spec.rb
expect(post).not_to be_valid
end
end
+ context "par maxlength" do
+ context "Pour 30 caractères" do
+ it "Devenir valide" do
+ post = Post.new(subject: "Ah" * 30, body: "fuga")
+ expect(post).to be_valid
+ end
+ end
+ context "Pour 31 caractères" do
+ it "Devenir invalide" do
+ post = Post.new(subject: "Ah" * 31, body: "fuga")
+ expect(post).not_to be_valid
+ end
+ end
+ end
end
end
Faisons un test.
$ rspec ./spec/models/post_spec.rb
...
Finished in 0.03204 seconds (files took 1.42 seconds to load)
3 examples, 1 failure
Failed examples:
rspec ./spec/models/post_spec.rb:21 #La longueur maximale du sujet du message le rend invalide pour 31 caractères
Je n'ai pas encore ajouté de validation, donc 30 caractères passeront mais 31 caractères seront de la mousse. Ajoutez une validation au modèle.
app/models/post.rb
class Post < ApplicationRecord
- validates :subject, presence: true
+ validates :subject, presence: true, length: { maximum: 30 }
end
$ rspec ./spec/models/post_spec.rb
...
Finished in 0.02201 seconds (files took 1.4 seconds to load)
3 examples, 0 failures
Vous avez réussi le test.
Cela entraînera une erreur à 31 caractères. Essayez-le avec rails c
.
Par exemple, dans le code de test ci-dessus
post = Post.new(subject: "Ah" * 30, body: "fuga")
Cependant, il est difficile de spécifier le corps à chaque fois. Ce n'est toujours pas grave s'il s'agit de 2 colonnes, mais s'il dépasse 10 colonnes, le code sera inutilement long. À ce moment-là, utilisez factoryBot.
Le factoryBot regarde sous spec / usines /. Cette fois, il n'est pas nécessaire de changer la valeur initiale lors de la création du modèle, mais regardons le contenu.
spec/factories/posts.rb
# frozen_string_literal: true
FactoryBot.define do
factory :post do
subject { "MyString" }
body { "MyText" }
end
end
Modifiez le fichier post_spec.rb.
spec/models/post_spec.rb
describe "subject" do
context "Lorsque vide" do
it "Devenir invalide" do
- post = Post.new(subject: "", body: "fuga")
+ post = build(:post, subject: "")
expect(post).not_to be_valid
end
end
context "par maxlength" do
context "Pour 30 caractères" do
it "Devenir valide" do
- post = Post.new(subject: "Ah" * 30, body: "fuga")
+ post = build(:post, subject: "Ah" * 30)
expect(post).to be_valid
end
end
context "Pour 31 caractères" do
it "Devenir invalide" do
- post = Post.new(subject: "Ah" * 31, body: "fuga")
+ post = build(:post, subject: "Ah" * 31)
expect(post).not_to be_valid
end
end
build est l'équivalent de .new
en utilisant factoryBot. Il n'est pas enregistré dans la base de données.
Dans ce cas, le sujet est spécifié, mais le corps n'est pas spécifié, donc le corps du factoryBot contiendra «" MyText "».
Exécutez également un test pour chaque modification pour vous assurer qu'elle est correcte.
Pour le moment, essayez de le changer comme suit.
spec/models/post_spec.rb
RSpec.describe Post, type: :model do
describe "subject" do
context "Lorsque vide" do
+ let(:post) do
+ build(:post, subject: "")
+ end
it "Devenir invalide" do
- post = build(:post, subject: "")
expect(post).not_to be_valid
end
end
context "par maxlength" do
context "Pour 30 caractères" do
+ let(:post) do
+ build(:post, subject: "Ah" * 30)
+ end
it "Devenir valide" do
- post = build(:post, subject: "Ah" * 30)
expect(post).to be_valid
end
end
context "Pour 31 caractères" do
+ let(:post) do
+ build(:post, subject: "Ah" * 31)
+ end
it "Devenir invalide" do
- post = build(:post, subject: "Ah" * 31)
expect(post).not_to be_valid
end
end
let est une variable limitée à la portée du même bloc de description ou de contexte. Dans Ruby, la dernière expression évaluée est la valeur de retour, donc
let(:post) do
build(:post, subject: "Ah" * 31)
end
Dans le cas de, le post du résultat de l'exécution de la construction devient une variable appelée post par let (: post)
.
Implémentons le test et la validation de la limite obligatoire et de la limite de 100 caractères ou moins sur le corps.
spec/models/post_spec.rb
# frozen_string_literal: true
require "rails_helper"
RSpec.describe Post, type: :model do
describe "subject" do
context "Lorsque vide" do
let(:post) do
build(:post, subject: "")
end
it "Devenir invalide" do
expect(post).not_to be_valid
end
end
context "par maxlength" do
context "Pour 30 caractères" do
let(:post) do
build(:post, subject: "Ah" * 30)
end
it "Devenir valide" do
expect(post).to be_valid
end
end
context "Pour 31 caractères" do
let(:post) do
build(:post, subject: "Ah" * 31)
end
it "Devenir invalide" do
expect(post).not_to be_valid
end
end
end
end
describe "body" do
context "Lorsque vide" do
let(:post) do
build(:post, body: "")
end
it "Devenir invalide" do
expect(post).not_to be_valid
end
end
context "par maxlength" do
context "Pour 100 caractères" do
let(:post) do
build(:post, body: "Ah" * 100)
end
it "Devenir valide" do
expect(post).to be_valid
end
end
context "Pour 101 caractères" do
let(:post) do
build(:post, body: "Ah" * 101)
end
it "Devenir invalide" do
expect(post).not_to be_valid
end
end
end
end
end
Si vous exécutez rspec à ce stade, ce sera de la mousse
app/models/post.rb
# frozen_string_literal: true
#
#Après la classe
#
class Post < ApplicationRecord
validates :subject, presence: true, length: { maximum: 30 }
validates :body, presence: true, length: { maximum: 100 }
end
Réglage d'exclusion car le rubocop est de la mousse. Il vaut mieux ne pas être trop strict car le test peut être contre-productif si vous respectez les normes DRY et de codage.
diff:.rubocop.yml
+ #Longueur de bloc
+ Metrics/BlockLength:
+ Exclude:
+ - "spec/**/*"
À ce stade, si vous exécutez rspec et rubocop, il passera.
[Vers la table de sérialisation]
Recommended Posts