[RUBY] # 4 nach Validierung und Testimplementierung zum Erstellen einer Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6

Erstellen einer Bulletin Board-API mit Zertifizierungsberechtigung mit Rails 6 # 3 RSpec, FactoryBot wird eingeführt und ein Post-Modell erstellt

Schreiben Sie einen Modelltest mit RSpec

Vorläufig konnte ich bestätigen, dass beim letzten Mal Arbeiten erstellt und gelesen wurden. Folgen Sie von hier aus diesem Verfahren

  1. Schreiben Sie einen Modelltest für die Post
  2. Implementieren Sie die Validierung
  3. Schreiben Sie einen Post-Controller-Test
  4. Schreiben Sie den Controller und die Routen
  5. Schreibe Samen

In diesem Artikel werde ich vorerst 1 und 2 implementieren und nach 3 werde ich mit dem nächsten und den folgenden Artikeln fortfahren.

Rubocop im Voraus zerdrücken

Schreiben eines Dokuments Schließen Sie den Fehler aus, wie er in der Migrationsdatei angezeigt wird.

.rubocop.yml kann auf diese Weise ausgeschlossen werden. Wenn Sie jedoch ausschließen, was Sie ursprünglich benötigen, wird die Bedeutung der Einhaltung des Codierungsstandards in erster Linie verletzt. Lassen Sie uns dies also beim Hinzufügen in der Teamentwicklung ausführlich diskutieren. ..

diff:.rubocop.yml


+ #Dokumentation
+ Style/Documentation:
+  Exclude:
+    - "db/migrate/**/*"
...

Schreiben Sie zuerst einen Modelltest

Wie bei Test Driven Development (TDD) ist der erste Test von Red. Da die Validierung nicht implementiert ist, werde ich etwas machen, das rot ist, selbst wenn ich einen Test schreibe und ihn ausführe.

Ich werde es in einem normalen Rails-Tick schreiben, ohne factory_bot einmal zu verwenden.

spec/models/post_spec.rb


# frozen_string_literal: true

require "rails_helper"

RSpec.describe Post, type: :model do
  describe "subject" do
    context "Wenn leer" do
      it "Ungültig werden" do
        post = Post.new(subject: "", body: "fuga")
        expect(post).not_to be_valid
      end
    end
  end
end

Der obige Code testet also, dass "er ungültig wird, wenn der Betreff leer ist". Bisher habe ich das Thema des Post-Modells jedoch nicht validiert, sodass der Post gültig ist und der "ungültige" Test fehlschlägt.

$ 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 #Ungültig, wenn Betreff des Beitrags leer ist

ec2-user:~/environment/bbs (master) $ rspec

Versuchen wir, uns zu registrieren, auch wenn das Thema leer ist.

$ 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>

Du hast es gespeichert.

Übrigens ohne Beschreibung oder Kontext

spec/models/post_spec.rb


# frozen_string_literal: true

require "rails_helper"

RSpec.describe Post, type: :model do
  it "Ungültig, wenn das Thema leer ist" do
    post = Post.new(subject: "", body: "fuga")
    expect(post).not_to be_valid
  end
end

Das Verhalten des Testcodes ist nahezu identisch. Dies liegt daran, dass Sie testen können, indem Sie Expect in den it-Block schreiben. Es wird jedoch schwierig zu verstehen, wenn dieselbe Spalte und dieselben Validierungsbedingungen durch Gruppierung beschrieben werden. Daher wird grundsätzlich empfohlen, diese durch Verschachtelung von Beschreibung und Kontext zu beschreiben.

Fügen Sie dem Modell eine Validierung hinzu

Validierung mit Leerzeichen als Fehler

app/models/post.rb


 class Post < ApplicationRecord
+  validates :subject, presence: true
 end

Jetzt können Sie sich nicht mehr mit true oder blank für die Anwesenheit in der Betreffspalte registrieren.

Lass es uns versuchen.

$ 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'

Ich kann mich nicht registrieren.

$ rspec ./spec/models/post_spec.rb 
...
Finished in 0.05053 seconds (files took 1.63 seconds to load)
1 example, 0 failures

Der Test hat auch bestanden.

Validierung der maximalen Anzahl von Zeichen

Da es ein Problem wäre, wenn die Anzahl der Zeichen unendlich registriert werden könnte, werden wir ein Limit hinzufügen. Dies ist auch aus dem Test zuerst. Ich werde einen Test mit einem Plan schreiben, um die Validierung hinzuzufügen, dass es in Ordnung ist, wenn es 30 Zeichen oder weniger ist, und NG, wenn es 31 Zeichen oder mehr ist.

spec/models/post_spec.rb


         expect(post).not_to be_valid
       end
     end
+    context "durch maximale Länge" do
+      context "Für 30 Zeichen" do
+        it "Werden Sie gültig" do
+          post = Post.new(subject: "Ah" * 30, body: "fuga")
+          expect(post).to be_valid
+        end
+      end
+      context "Für 31 Zeichen" do
+        it "Ungültig werden" do
+          post = Post.new(subject: "Ah" * 31, body: "fuga")
+          expect(post).not_to be_valid
+        end
+      end
+    end
   end
 end

Lassen Sie uns einen Test durchführen.

$ 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 #Die maximale Länge des Post-Betreffs macht ihn für 31 Zeichen ungültig

Ich habe noch keine Validierung hinzugefügt, daher werden 30 Zeichen übergeben, aber 31 Zeichen sind Moos. Fügen Sie dem Modell eine Validierung hinzu.

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

Sie haben den Test bestanden. Dies führt zu einem Fehler bei 31 Zeichen. Versuchen Sie es mit "Schienen c".

Durch FactoryBot ersetzen

Zum Beispiel im obigen Testcode

  post = Post.new(subject: "Ah" * 30, body: "fuga")

Es ist jedoch schwierig, den Körper jedes Mal anzugeben. Es ist immer noch in Ordnung, wenn es 2 Spalten sind, aber wenn es 10 Spalten überschreitet, wird der Code unnötig lang sein. Verwenden Sie zu diesem Zeitpunkt factoryBot.

Der factoryBot sieht unter spec / factories / aus. Dieses Mal muss der Anfangswert beim Erstellen des Modells nicht geändert werden. Schauen wir uns jedoch den Inhalt an.

spec/factories/posts.rb


# frozen_string_literal: true

FactoryBot.define do
  factory :post do
    subject { "MyString" }
    body { "MyText" }
  end
end

Bearbeiten Sie die Datei post_spec.rb.

spec/models/post_spec.rb


   describe "subject" do
     context "Wenn leer" do
       it "Ungültig werden" do
-        post = Post.new(subject: "", body: "fuga")
+        post = build(:post, subject: "")
         expect(post).not_to be_valid
       end
     end
     context "durch maximale Länge" do
       context "Für 30 Zeichen" do
         it "Werden Sie gültig" do
-          post = Post.new(subject: "Ah" * 30, body: "fuga")
+          post = build(:post, subject: "Ah" * 30)
           expect(post).to be_valid
         end
       end
       context "Für 31 Zeichen" do
         it "Ungültig werden" do
-          post = Post.new(subject: "Ah" * 31, body: "fuga")
+          post = build(:post, subject: "Ah" * 31)
           expect(post).not_to be_valid
         end
       end

build ist das Äquivalent von .new mit factoryBot. Es wird nicht in der Datenbank gespeichert. In diesem Fall wird der Betreff angegeben, der Text jedoch nicht. Daher enthält der Text des factoryBot "MyText".

Führen Sie außerdem für jede Änderung einen Test durch, um sicherzustellen, dass sie in Ordnung ist.

Variable durch let ersetzen

Versuchen Sie es vorerst wie folgt zu ändern.

spec/models/post_spec.rb


 RSpec.describe Post, type: :model do
   describe "subject" do
     context "Wenn leer" do
+      let(:post) do
+        build(:post, subject: "")
+      end
       it "Ungültig werden" do
-        post = build(:post, subject: "")
         expect(post).not_to be_valid
       end
     end
     context "durch maximale Länge" do
       context "Für 30 Zeichen" do
+        let(:post) do
+          build(:post, subject: "Ah" * 30)
+        end
         it "Werden Sie gültig" do
-          post = build(:post, subject: "Ah" * 30)
           expect(post).to be_valid
         end
       end
       context "Für 31 Zeichen" do
+        let(:post) do
+          build(:post, subject: "Ah" * 31)
+        end
         it "Ungültig werden" do
-          post = build(:post, subject: "Ah" * 31)
           expect(post).not_to be_valid
         end
       end

let ist eine Variable, die auf den Bereich innerhalb desselben Beschreibungs- oder Kontextblocks beschränkt ist. In Ruby ist der zuletzt ausgewertete Ausdruck der Rückgabewert

  let(:post) do
    build(:post, subject: "Ah" * 31)
  end

Im Fall von wird der Beitrag des Build-Ausführungsergebnisses zu einer Variablen namens post von let (: post).

Übung

Lassen Sie uns den Test und die Validierung des obligatorischen Limits und des Limits von 100 Zeichen oder weniger für den Body implementieren.

Antwortbeispiel für die Body-Implementierung

spec/models/post_spec.rb


# frozen_string_literal: true

require "rails_helper"

RSpec.describe Post, type: :model do
  describe "subject" do
    context "Wenn leer" do
      let(:post) do
        build(:post, subject: "")
      end
      it "Ungültig werden" do
        expect(post).not_to be_valid
      end
    end
    context "durch maximale Länge" do
      context "Für 30 Zeichen" do
        let(:post) do
          build(:post, subject: "Ah" * 30)
        end
        it "Werden Sie gültig" do
          expect(post).to be_valid
        end
      end
      context "Für 31 Zeichen" do
        let(:post) do
          build(:post, subject: "Ah" * 31)
        end
        it "Ungültig werden" do
          expect(post).not_to be_valid
        end
      end
    end
  end

  describe "body" do
    context "Wenn leer" do
      let(:post) do
        build(:post, body: "")
      end
      it "Ungültig werden" do
        expect(post).not_to be_valid
      end
    end
    context "durch maximale Länge" do
      context "Für 100 Zeichen" do
        let(:post) do
          build(:post, body: "Ah" * 100)
        end
        it "Werden Sie gültig" do
          expect(post).to be_valid
        end
      end
      context "Für 101 Zeichen" do
        let(:post) do
          build(:post, body: "Ah" * 101)
        end
        it "Ungültig werden" do
          expect(post).not_to be_valid
        end
      end
    end
  end
end

Wenn Sie an dieser Stelle rspec ausführen, handelt es sich um Moos

app/models/post.rb


# frozen_string_literal: true

#
#Post Klasse
#
class Post < ApplicationRecord
  validates :subject, presence: true, length: { maximum: 30 }
  validates :body, presence: true, length: { maximum: 100 }
end

Ausschlusseinstellung, da Rubocop Moos ist. Es ist besser, nicht zu streng zu sein, da der Test kontraproduktiv sein kann, wenn Sie die DRY- und Codierungsstandards einhalten.

diff:.rubocop.yml


+ #Blocklänge
+ Metrics/BlockLength:
+   Exclude:
+     - "spec/**/*"

Wenn Sie zu diesem Zeitpunkt rspec und rubocop ausführen, wird es bestanden.

Fortsetzung

Erstellen einer Bulletin Board-API mit Zertifizierung und Autorisierung im Rails 6 # 5-Controller, Routenimplementierung

[Zur Serialisierungstabelle]

Recommended Posts

# 4 nach Validierung und Testimplementierung zum Erstellen einer Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6
Erstellen Sie mit Rails 6 # 18 eine Bulletin-Board-API mit Zertifizierung und Autorisierung. ・ Implementierung des Endbenutzer-Controllers
Erstellen Sie eine Bulletin-Board-API mit Autorisierung in Rails 6 # 12 Assoziation von Benutzer und Beitrag
Erstellen Sie eine Bulletin-Board-API mit Autorisierung in Rails 6 # 11. Benutzermodelltest und Validierung hinzugefügt
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung mit Rails 6 # 3 RSpec. FactoryBot wird eingeführt und ein Post-Modell erstellt
Erstellen Sie eine Bulletin-Board-API mit Zertifizierung und Autorisierung mit Rails 6 # 1 Environment Construction
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung im Rails 6 # 5-Controller und leiten Sie die Implementierung weiter
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6 # 2 Einführung in Git und Rubocop
# 8 Seed-Implementierung zum Erstellen einer Bulletin Board-API mit Zertifizierungsautorisierung in Rails 6
Erstellen Sie eine Bulletin Board-API mit Zertifizierungsberechtigung in Rails 6 # 13 Grant-Authentifizierungsheader
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6 # 6. Zeigen Sie, erstellen Sie die Implementierung
Einführung von # 10 devise_token_auth zum Erstellen einer Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6
Einführung des Experten Nr. 15 zum Erstellen einer Bulletin-Board-API mit Zertifizierung und Autorisierung in Rails 6
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6 # 17. Fügen Sie Administratorrechte hinzu
Erstellen Sie eine Bulletin Board-API mit Zertifizierungsberechtigung im Rails 6 # 7-Update und zerstören Sie die Implementierung
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6 # 14 Seed. Anzeige der Ausführungszeit
# 16 Richtlinieneinstellung zum Erstellen einer Bulletin Board-API mit Zertifizierungsberechtigung in Rails 6
Einführung des Serializers Nr. 9 zum Erstellen einer Bulletin-Board-API mit Zertifizierung und Autorisierung in Rails 6
[Rails] Implementierung der Drag & Drop-Funktion (mit Wirkung)
Ich habe versucht, die Rails-API mit TDD von RSpec zu implementieren. Teil3-Aktionsimplementierung mit Authentifizierung
Ich habe versucht, mit Rails eine Gruppenfunktion (Bulletin Board) zu erstellen
Ich habe versucht, die Rails-API mit TDD von RSpec zu implementieren. Teil1-Aktionsimplementierung ohne Authentifizierung-
Erstellen einer Rails 6- und PostgreSQL-Umgebung mit Docker
[Rails] Implementierung einer Validierung, die die Eindeutigkeit beibehält
Ich habe versucht, die Telefonnummer (Festnetz / Mobiltelefon) mit einem regulären Ausdruck in Rails auszudrücken und Validierung und Test zu schreiben
Erstellen Sie mit Java + MySQL ein einfaches Bulletin Board
[Nuxt / Rails] POST-Implementierung mit axios und devise_token_auth
So erstellen Sie eine API mit GraphQL und Rails