[RUBY] [1st] RSpec-Anfänger haben versucht, Model Spec als Anfänger zu schreiben

Einführung

Freut mich, dich kennenzulernen. Zunächst möchte ich mich kurz vorstellen. Von Mai 2020 bis September 2020 bin ich Absolvent, der hauptsächlich Ruby am DMM WEB CAMP studiert hat und derzeit den Job wechselt. Neulich eine Lernsitzung für Anfänger mit der Freundlichkeit des RSpec-Mannes Junichi Ito @jnchito (RSpec Beginners !!).

Ich hatte das Gefühl, als ich einen Test mit RSpec im Portfolio schrieb, Wenn Sie ein Anfänger wie ich sind, habe ich die "Stolperpunkte" wie "Ich werde hier stolpern: Denken:" und "Ich weiß hier nicht: Umarmen:" aus der Sicht eines Anfängers zusammengefasst. Außerdem wollte ich im Laufe der Zeit manchmal ein konkretes Testcodebeispiel für die Funktion, die ich schreiben wollte, und diene daher auch als Überprüfung meiner selbst, aber wenn dieser Artikel für RSpec-Anfänger ein wenig hilfreich ist Ich bin glücklich.

Was ist in diesem Artikel zu tun?

In diesem Artikel nicht behandelt

Annahme

Testen des einzelnen Benutzermodells

① Einführung des individuellen Benutzermodells

Zunächst zeige ich Ihnen das individuelle Benutzermodell. Eigentlich gibt es Assoziationen wie Lieblingsmodelle, aber wir werden uns diesmal nicht mit ihnen befassen, deshalb haben wir sie absichtlich gelöscht.

①user.rb


class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_many :rooms, dependent: :destroy
  has_many :messages, dependent: :destroy
  has_many :notifications, dependent: :destroy
  
  validates :last_name, presence: true, length: { maximum: 10 }
  validates :first_name, presence: true, length: { maximum: 10 }
  validates :kana_last_name, presence: true, length: { maximum: 10 }
  validates :kana_first_name, presence: true, length: { maximum: 10 }
  validates :email, presence: true, length: { maximum: 30 }
  validates :postal_code, presence: true, length: { minimum: 7, maximum: 7 }
  validates :address, presence: true, length: { maximum: 30 }
  validates :phone_number, presence: true, length: { maximum: 12 }
  validates :introduction, length: { maximum: 200 }

  attachment :profile_image

  def full_name
    last_name + " " + first_name
  end

  def kana_full_name
    kana_last_name + " " + kana_first_name
  end
end

(2) Verwenden Sie FactoryBot und bereiten Sie Benutzerdaten im Voraus vor.

** Stolperpunkt: Umarmen: "Was ist FactoryBot?" ** FactoryBot wird auch in "Alltägliche Rails-Einführung in Rails-Tests mit RSpec" beschrieben. Sie können es verwenden, indem Sie einen Edelstein einfügen, sodass Sie versuchen können, mit FactoryBot zu suchen. Ich wusste es zuerst nicht, aber es ist okay. Es ist nur praktisch, dass Sie die Testdaten einfach beschreiben und einer Instanzvariablen oder lokalen Variablen wie @user in ③ zuweisen können. Die Verwendung ist in ③ beschrieben. Führen Sie zunächst $ bin / rails g factory_bot: model user aus, um eine Datei zu erstellen. Versuchen Sie nach dem Erstellen, Beispieldaten gemäß den Spalten Ihrer Anwendung einzufügen.

②spec/factories/users.rb


FactoryBot.define do
  #Verwenden Sie FactoryBot und bereiten Sie Benutzerdaten im Voraus vor
  factory :user do
    last_name { "Prüfung" }
    first_name { "Taro" }
    kana_last_name { "Prüfung" }
    kana_first_name { "Taro" }
    email { "[email protected]" }
    postal_code { "1234567" }
    address { "123, Chiyoda-ku, Tokio-12-1" }
    phone_number { "12345678910" }
    password { "testtaro" }
  end
end

③ Spezifische Testbeschreibung

Ich werde endlich einen Test schreiben. seien Sie versichert. Ich werde später richtig stolpern. Wenn Sie $ bin / rails g rspec: model user ausführen, wird user_spec.rb im Ordner spec / models erstellt. Der Testcode des Modells (Validierung, selbst erstellte Methode usw.) wird in diese Datei geschrieben.

Unten finden Sie ein vollständiges Beispiel.

③spec/models/user_spec.rb


require 'rails_helper'

RSpec.describe User, type: :model do

  before do
    @user = FactoryBot.build(:user)
  end

  describe "Validierungstest" do
    it "Nachname, Vorname, Kana-Nachname, Kana-Vorname, Post, Postleitzahl, Adresse, Telefonnummer, Passwort müssen gültig sein" do
      expect(@user).to be_valid
    end

    it "Muss ohne Nachnamen ungültig sein" do
      @user.last_name = ""
      @user.valid?
      expect(@user.errors[:last_name]).to include("Bitte eingeben")
    end

    it "Muss ungültig sein, es sei denn, der Nachname darf maximal 10 Zeichen lang sein" do
      @user.last_name = "a" * 11
      @user.valid?
      expect(@user.errors[:last_name]).to include("Bitte geben Sie innerhalb von 10 Zeichen ein")
    end

    it "Wenn kein Name vorhanden ist, befindet er sich in einem ungültigen Zustand" do
      @user.first_name = ""
      @user.valid?
      expect(@user.errors[:first_name]).to include("Bitte eingeben")
    end

    it "Der Name darf maximal 10 Zeichen lang und ungültig sein" do
      @user.first_name = "a" * 11
      @user.valid?
      expect(@user.errors[:first_name]).to include("Bitte geben Sie innerhalb von 10 Zeichen ein")
    end
    
    it "Muss ohne Kana Nachnamen ungültig sein" do
      @user.kana_last_name = ""
      @user.valid?
      expect(@user.errors[:kana_last_name]).to include("Bitte eingeben")
    end

    it "Kana Nachname darf maximal 10 Zeichen lang sein, um ungültig zu sein" do
      @user.kana_last_name = "a" * 11
      @user.valid?
      expect(@user.errors[:kana_last_name]).to include("Bitte geben Sie innerhalb von 10 Zeichen ein")
    end

    it "Wenn es keinen Kana-Namen gibt, befindet er sich in einem ungültigen Zustand" do
      @user.kana_first_name = ""
      @user.valid?
      expect(@user.errors[:kana_first_name]).to include("Bitte eingeben")
    end

    it "Der Kana-Name darf maximal 10 Zeichen lang sein, um ungültig zu sein" do
      @user.kana_first_name = "a" * 11
      @user.valid?
      expect(@user.errors[:kana_first_name]).to include("Bitte geben Sie innerhalb von 10 Zeichen ein")
    end
    
    it "Muss ohne E-Mail-Adresse ungültig sein" do
      @user.email = ""
      @user.valid?
      expect(@user.errors[:email]).to include("Bitte eingeben")
    end

    it "Die E-Mail-Adresse darf maximal 30 Zeichen lang sein, um ungültig zu sein" do
      @user.email = "a" * 31
      @user.valid?
      expect(@user.errors[:email]).to include("Bitte geben Sie 30 Zeichen oder weniger ein.")
    end
    
    it "Wenn es keine Postleitzahl gibt, ist sie ungültig" do
      @user.postal_code = ""
      @user.valid?
      expect(@user.errors[:postal_code]).to include("Bitte eingeben")
    end

    it "Wenn die Postleitzahl weniger als 7 Zeichen enthält, ist sie ungültig" do
      @user.postal_code = "a" * 6
      @user.valid?
      expect(@user.errors[:postal_code]).to include("Bitte geben Sie mindestens 7 Zeichen ein")
    end

    it "Wenn die Postleitzahl 7 Zeichen überschreitet, ist sie ungültig." do
      @user.postal_code = "a" * 8
      @user.valid?
      expect(@user.errors[:postal_code]).to include("Bitte geben Sie innerhalb von 7 Zeichen ein")
    end
    
    it "Muss ohne Adresse ungültig sein" do
      @user.address = ""
      @user.valid?
      expect(@user.errors[:address]).to include("Bitte eingeben")
    end

    it "Die Adresse darf maximal 30 Zeichen lang sein, um ungültig zu sein" do
      @user.address = "a" * 31
      @user.valid?
      expect(@user.errors[:address]).to include("Bitte geben Sie innerhalb von 30 Zeichen ein")
    end
    
    it "Wenn keine Telefonnummer vorhanden ist, ist diese ungültig" do
      @user.phone_number = ""
      @user.valid?
      expect(@user.errors[:phone_number]).to include("Bitte eingeben")
    end

    it "Die Telefonnummer darf maximal 12 Zeichen lang sein, um ungültig zu sein" do
      @user.phone_number = "a" * 13
      @user.valid?
      expect(@user.errors[:phone_number]).to include("Bitte geben Sie innerhalb von 12 Zeichen ein")
    end

    it "Der Selbsteinführungstext darf maximal 200 Zeichen lang sein, um ungültig zu sein." do
      @user.introduction = "a" * 201
      @user.valid?
      expect(@user.errors[:introduction]).to include("Bitte geben Sie innerhalb von 200 Zeichen ein")
    end

    it "Das Passwort muss aus 6 Zeichen oder mehr bestehen und ist ungültig" do
      @user.password = "a" * 5
      @user.valid?
      expect(@user.errors[:password]).to include("Bitte geben Sie mindestens 6 Zeichen ein.")
    end
    
    it "Eine doppelte E-Mail-Adresse muss ungültig sein" do
      FactoryBot.create(:user)
      @user.valid?
      expect(@user.errors[:email]).to include("Ist bereits vorhanden.")
    end
  end

  describe "Instanzmethoden testen" do
    it "Rückgabe des vollständigen Namens des Benutzers als Zeichenfolge" do
      @user.last_name = "Prüfung"
      @user.first_name = "Taro"
      expect(@user.full_name).to eq "Testen Sie Taro"
    end

    it "Rückgabe des canaful-Namens des Benutzers als Zeichenfolge" do
      @user.kana_last_name = "Prüfung"
      @user.kana_first_name = "Taro"
      expect(@user.kana_full_name).to eq "Testen Sie Taro"
    end
  end

end

"Hmmm, ich werde den Testcode in diese Datei schreiben. OK: vulcan: Ich verstehe nicht wirklich von der ersten Zeile an! ** require'rails_helper '** Was ist das: umarmen:" Diejenigen, die dachten. Dies teilt RSpec mit, dass eine Rails-Anwendung geladen werden muss, um die Tests in der Datei auszuführen. Diese Beschreibung ist für fast jede Datei in der Testsuite erforderlich. (Zitiert aus Everyday Rails) Ich fange an zu denken, dass ich nichts über Everyday Rails erklären muss, aber ich werde mein Bestes geben.

Kurz gesagt, durch Schreiben von "rrails_helper" für RSpec-Senioren ** "Meine Anwendung sieht so aus! Das Modell hat diese Art von Daten, der Controller hat diese Art von Beschreibung und die Ansicht zeigt dies! Bitte verstehen Sie!" ** Das sage ich dir. Dank dieser Beschreibung testet RSpec die Anwendung anhand des von Ihnen geschriebenen Codes.

Was ist das für ein Rails_Helper? Diejenigen, die dachten. Rspec-Einstellungen können in ** rails_helper.rb ** im Spezifikationsordner geschrieben werden. Hier wird auch die Einstellung geschrieben, mit der die Hilfsmethode von devise in system_spec verwendet werden kann, die in den Systemspezifikationen verwendet wird, die beim nächsten Mal beschrieben werden.

Der Teil dieser Einstellung usw. wird auch in Everyday Rails beschrieben. Ich verlasse mich wirklich auf Everyday Rails, aber ich empfehle es, weil es ein Buch ist, das spezifische Beschreibungen des Testcodes enthält und warum diese Beschreibung notwendig ist.

spec/rails_helper.rb


#Entwickeln Sie ein Hilfsmethoden-System_Zur Verfügung stellen in spec
  config.include Devise::Test::IntegrationHelpers, type: :system

Ich bin mir sicher, dass es Leute gibt, die sagen: "Ich verstehe rails_helper irgendwie, aber ich weiß nicht, ob nur der vollständige Code darunter angezeigt wird: hugging:", also erkläre ich es kurz. Da ich jedoch mehr über das Testen des Benutzermodells in Everyday Rails geschrieben habe, ist es möglicherweise besser, darauf zu verweisen.

Siehe das folgende Codebeispiel. Erstens wird der Vorher-Block verwendet, um den Code DRY zu machen, wenn mehrere Tests in derselben Datei dieselben Daten erfordern. In diesem Fall werden die in (2) oben beschriebenen Testdaten von spec / factories / users.rb erstellt und @user durch die Beschreibung von FactoryBot.build (: user) auf der rechten Seite zugewiesen. Auf diese Weise kann @user später im it-Block usw. verwendet werden. Überschreiben Sie die leeren Daten für den Nachnamen mit @ user.last_name = "" in der ersten Zeile des it-Blocks, z. B. "Wenn @ user.last_name null ist, ist sie ungültig ~" oder @ user.last_name = "a" * Es fühlt sich so an, als würde ich einen Test wie "Nachname wird validiert, also ist er ungültig, es sei denn, er besteht aus 10 Zeichen oder weniger" schreiben, indem ich die Daten "aaaaaaaaaaaa" in Nachname in 11 überschreibe. Das be_valid davor heißt übrigens Matcher. In Bezug auf Matcher, Mr. Itos [Einführung in RSpec, die verwendet werden kann, Teil 2 "Beherrschen häufig verwendeter Matcher" ](Https://qiita.com/jnchito/items/2e79a1abe7cd8214caa5 "Einführung in RSpec, das verwendet werden kann, Teil 2" Beherrschen häufig verwendeter Matcher " Ich denke, Sie sollten sich auf ") beziehen.

** Stolperpunkt: Umarmen: "Factory Bot Description Position" ** Wenn Sie einen Vorher-Block direkt unter RSpec.describe User platzieren, geben Sie :: model do ein und beschreiben Sie @user, der von FactoryBot erstellt wurde. @Benutzer im Vorher-Block befindet sich alle in derselben Datei. Es kann in Tests verwendet werden. Diesmal ist es immer noch eine einfache Zuordnung, daher ist es besser, aber mit zunehmender Anzahl von Zuordnungen werden immer mehr Daten mit FactoryBot erstellt, und ich bin süchtig nach der Position, die ich zu diesem Zeitpunkt beschreiben möchte. Insbesondere Systemspezifikation. Es war ein Sumpf. Ich werde später darüber sprechen.

③spec/models/user_spec.rb


RSpec.describe User, type: :model do
#Der Vorher-Block wird verwendet, um den Code DRY zu machen, wenn dieselben Daten für mehrere Tests in derselben Datei erforderlich sind.
 before do
   @user = FactoryBot.build(:user) # @zuletzt für Benutzer_name{ "Prüfung" }、first_name { "Taro" }Enthält Daten wie
 end

 it "Nachname, Vorname, Kana-Nachname, Kana-Vorname, Post, Postleitzahl, Adresse, Telefonnummer, Passwort müssen gültig sein" do
   expect(@user).to be_valid
 end

 it "Muss ohne Nachnamen ungültig sein" do
   @user.last_name = "" # @user.last_Wenn der Name Null ist, ist er ungültig ~
   @user.valid?
   expect(@user.errors[:last_name]).to include("Bitte eingeben")
 end

 it "Muss ungültig sein, es sei denn, der Nachname darf maximal 10 Zeichen lang sein" do
   @user.last_name = "a" * 11 # last_Da der Name überprüft wird, ist er ungültig, es sei denn, er besteht aus 10 Zeichen oder weniger ~
   @user.valid?
   expect(@user.errors[:last_name]).to include("Bitte geben Sie innerhalb von 10 Zeichen ein")
 end

Außerdem sehen nur die folgenden Tests etwas anders aus. FactoryBot.create (: user) steht in der ersten Zeile. In dem oben erwähnten Vorher-Block wird @user vor dem It-Block erstellt. So ist dieser Test. @Benutzer im Vorher-Block ist diesmal jedoch ** erstellen **, nicht erstellen, sodass es nicht in der Datenbank gespeichert wird, es sei denn, es wird gespeichert. Wenn Sie im folgenden Test FactoryBot.create (: user) in die erste Zeile schreiben, wird dies vor @user im Vorher-Block in der angegebenen Reihenfolge gespeichert. Wenn Sie danach @ user.valid? (Ist @user gültig?) Fragen, werden dieselben Daten zuerst gespeichert, sodass Sie erwarten können, dass der Wortlaut include ("existiert bereits"). Richtig.

③spec/models/user_spec.rb


it "Eine doppelte E-Mail-Adresse muss ungültig sein" do
  FactoryBot.create(:user) #Zuerst gespeichert
  @user.valid?
  expect(@user.errors[:email]).to include("Ist bereits vorhanden.")
end

Der Rest der it-Blöcke hat die gleiche Struktur, und ich denke, sie können irgendwie verstanden werden, also werde ich sie falten. Bitte beachten Sie, dass der Include-Teil (bitte geben Sie "" ein) der Erwartung je nach Person unterschiedliche Fehleraussagen enthalten kann. Wenn Sie den Fehler von i18n ins Japanische übersetzt haben, überprüfen Sie ihn mit devise.ja.yml usw. oder überprüfen Sie die Fehleranweisung des Terminals zum Zeitpunkt der Ausführung. Überprüfen Sie also jeden Fehler und geben Sie den Wortlaut ein.


Testen Sie abschließend die Methode. Herr Ito erwähnte im RSpec Beginners-Video auch, dass es wichtig ist, die Validierung des Modells zu testen, aber es ist auch wichtig, die von Ihnen selbst erstellte Methode usw. zu testen **. Es scheint auch nicht notwendig zu sein, über den Assoziationstest zu schreiben. (Wenn der Name jedoch dupliziert wird und ein Pseudomodell mit class_name usw. erstellt wird (Follow-Funktion usw.), ist dies in Ordnung.) Es gibt Teile der Assoziationen, die Rails gut macht. Wenn Sie dies tun, sollten Sie sicherstellen, dass die von Ihnen erstellte Methode ordnungsgemäß funktioniert. Sicher dachte ich ~ ~ ~. Es wird im Video erwähnt, also schauen Sie bitte. Es ist also super einfach, aber ich werde unten auch einen Methodentest schreiben.

③spec/models/user_spec.rb


describe "Instanzmethoden testen" do
  it "Rückgabe des vollständigen Namens des Benutzers als Zeichenfolge" do
    @user.last_name = "Prüfung"
    @user.first_name = "Taro"
    expect(@user.full_name).to eq "Testen Sie Taro"
  end

  it "Rückgabe des canaful-Namens des Benutzers als Zeichenfolge" do
    @user.kana_last_name = "Prüfung"
    @user.kana_first_name = "Taro"
    expect(@user.kana_full_name).to eq "Testen Sie Taro"
  end
end

Nun, es ist leicht zu verstehen, ohne eine Erklärung, also werde ich es nicht erklären. Es ist nur so, dass die Methode full_name und die Methode kana_full_name, die im Modell von ① beschrieben sind, ordnungsgemäß vollständige Namen sind. Was das Testen von Methoden betrifft, kann ich nichts Kompliziertes schreiben, also werde ich es studieren. ..

Testen des Unternehmensbenutzermodells

Eigentlich gibt es Assoziationen wie das Beziehungsmodell, aber wir werden uns diesmal nicht mit ihnen befassen, deshalb haben wir sie absichtlich gelöscht. Da der Test für Unternehmensbenutzer fast der gleiche ist wie für einzelne Benutzer, wird nur der Code beschrieben. Beachten Sie daher Folgendes.

①company.rb


class Company < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_many :rooms, dependent: :destroy
  has_many :messages, dependent: :destroy
  has_many :articles, dependent: :destroy
  has_many :notifications, dependent: :destroy

  validates :company_name, presence: true, length: { maximum: 30 }
  validates :kana_company_name, presence: true, length: { maximum: 30 }
  validates :email, presence: true, length: { maximum: 30 }
  validates :postal_code, presence: true, length: { minimum: 7, maximum: 7 }
  validates :address, presence: true, length: { maximum: 30 }
  validates :phone_number, presence: true, length: { maximum: 12 }
  validates :introduction, length: { maximum: 800 }

  attachment :profile_image
  attachment :background_image

  #Wenn die Genehmigung wahr ist, können Sie sich anmelden. Zum Zeitpunkt der Neuregistrierung ist der Standardwert false, sodass Sie sich nicht anmelden können
  def active_for_authentication?
    super && self.approved?
  end

  #Die Nachricht nach dem Login wird oben umgedreht. Wortlautdetails sind config/locales/devise.ja.Beschrieben in yml.
  def inactive_message
    self.approved? ? super : :needs_admin_approval
  end

  def followed_by?(user)
    passive_relationships.find_by(following_id: user.id).present?
  end
end

②spec/factories/companies.rb


FactoryBot.define do
  factory :company do
    company_name { "Test Co., Ltd." }
    kana_company_name { "Test Co., Ltd." }
    email { "[email protected]" }
    postal_code { "1234567" }
    address { "123, Chiyoda-ku, Tokio-12-1" }
    phone_number { "12345678910" }
    password { "testcompany" }
    approved { true }
    is_active { true }
  end
end

③spec/models/company_spec.rb


require 'rails_helper'

RSpec.describe Company, type: :model do

  describe "Validierungstest" do

    before do
      @company = FactoryBot.build(:company)
    end

    it "Wenn Sie den Firmennamen, den Firmen-Kana-Namen, die E-Mail-Adresse, die Postleitzahl, die Adresse, die Telefonnummer und das Passwort haben, müssen diese gültig sein." do
      expect(@company).to be_valid
    end

    it "Es ist ohne den Firmennamen ungültig" do
      @company.company_name = ""
      @company.valid?
      expect(@company.errors[:company_name]).to include("Bitte eingeben")
    end

    it "Es ist ungültig, wenn kein Firmen-Kana-Name vorhanden ist" do
      @company.kana_company_name = ""
      @company.valid?
      expect(@company.errors[:kana_company_name]).to include("Bitte eingeben")
    end
    
    it "Muss ohne E-Mail-Adresse ungültig sein" do
      @company.email = ""
      @company.valid?
      expect(@company.errors[:email]).to include("Bitte eingeben")
    end
    
    it "Wenn es keine Postleitzahl gibt, ist sie ungültig" do
      @company.postal_code = ""
      @company.valid?
      expect(@company.errors[:postal_code]).to include("Bitte eingeben")
    end
    
    it "Muss ohne Adresse ungültig sein" do
      @company.address = ""
      @company.valid?
      expect(@company.errors[:address]).to include("Bitte eingeben")
    end
    
    it "Wenn keine Telefonnummer vorhanden ist, ist diese ungültig" do
      @company.phone_number = ""
      @company.valid?
      expect(@company.errors[:phone_number]).to include("Bitte eingeben")
    end

    it "Das Passwort muss aus 6 Zeichen oder mehr bestehen und ist ungültig" do
      @company.password = "a" * 5
      @company.valid?
      expect(@company.errors[:password]).to include("Bitte geben Sie mindestens 6 Zeichen ein")
    end
    
    it "Eine doppelte E-Mail-Adresse muss ungültig sein" do
      FactoryBot.create(:company)
      @company.valid?
      expect(@company.errors[:email]).to include("Ist bereits vorhanden")
    end
    
  end
end

Genre-Modelltest

Das Genre ist nicht besonders schwierig, daher werde ich die Erklärung weglassen.

①genre.rb


class Genre < ApplicationRecord
  has_many :articles, dependent: :destroy
  validates :genre_name, presence: true, length: { maximum: 15 }
end

②spec/factories/genres.rb


FactoryBot.define do
  factory :genre do
    genre_name { "Testgenre" }
    is_active { true }
  end
end

③spec/models/genre_spec.rb


require 'rails_helper'

RSpec.describe Genre, type: :model do
  describe "Validierungstest" do
    it "Wenn es keinen Genre-Namen gibt, ist er ungültig" do
      @genre = FactoryBot.build(:genre)
      @genre.genre_name = ""
      @genre.valid?
      expect(@genre.errors[:genre_name]).to include("Bitte eingeben")
    end
  end
end

Artikelmodellprüfung

① Einführung des Artikelmodells

Ich bin endlich da. Die Modellspezifikationen im Artikel unterscheiden sich geringfügig, daher möchte ich sie kurz erläutern. Unten ist das Artikelmodell.

①article.rb


class Article < ApplicationRecord
  belongs_to :company
  belongs_to :genre

  validates :title, presence: true, length: { maximum: 35 }
  validates :body, presence: true

  attachment :image

  #Suchen Sie nur nach Artikeln mit gültigem Veröffentlichungsstatus und gültigen Genres
  def self.all_active
    where(is_active: true).joins(:genre).where(genres: {is_active: true})
  end

  def favorited_by?(user)
    favorites.where(user_id: user.id).exists?
  end
end

② Verwenden Sie FactoryBot und bereiten Sie Artikeldaten im Voraus vor.

②spec/factories/articles.rb


FactoryBot.define do
  factory :article do
    title { "Testtitel" }
    body { "Testkörper" }
    is_active { true }
    company
    genre
  end
end

③ Spezifische Testbeschreibung

Ich werde einen Test des Artikelmodells schreiben. $ bin / rails g rspec: Modellartikel erstellt article_spec.rb im Ordner spec / models. Unten finden Sie ein Beispiel für den vollständigen Code.

③spec/models/article_spec.rb


require 'rails_helper'

RSpec.describe Article, type: :model do

  describe "Artikeltest" do
    before do
      @company = FactoryBot.create(:company)
      @genre = FactoryBot.create(:genre)
      @article = FactoryBot.build(:article)
    end

    #Artikelerstellung
    context "Wenn alle Daten enthalten sind" do
      it "Alle werden eingegeben, damit sie gespeichert werden" do
        @article.company_id = @company.id
        @article.genre_id = @genre.id
        expect(@article.save).to be true
      end
    end

    context "Wenn nicht alle Daten enthalten sind" do
      it "Nicht gespeichert, da nicht alle eingegeben wurden" do
        @article.company_id = @company.id
        @article.genre_id = @genre.id
        @article.title = ""
        @article.body = ""
        expect(@article.save).to be false
      end
    end
  end

  describe "Validierungstest" do
    before do
      @article = FactoryBot.build(:article)
    end

    context "Wenn der Titel nicht existiert" do
      it "In einem ungültigen Zustand sein" do
        @article.title = ""
        @article.valid?
        expect(@article.errors[:title]).to include("Bitte eingeben")
      end
    end

    context "Wenn der Titel mehr als 35 Zeichen enthält" do
      it "Ich erhalte eine Fehlermeldung" do
        @article.title = "a" * 36
        @article.valid?
        expect(@article.errors[:title]).to include("Bitte geben Sie innerhalb von 35 Zeichen ein")
      end
    end

    it "Wenn kein Text vorhanden ist, ist er ungültig" do
      @article.body = ""
      @article.valid?
      expect(@article.errors[:body]).to include("Bitte eingeben")
    end
    
  end
end

Nun, es gibt bisher nichts Neues, aber das Artikelmodell ist wie in ① beschrieben belongs_to :company belongs_to :genre Es ist eine solche Assoziation, und sie unterscheidet sich ein wenig von früher. Wie unten gezeigt, werden im Vorher-Block Firma und Genre zuerst mit FactoryBot erstellt, in der Datenbank gespeichert und dann @company bzw. @genre zugewiesen. Der Ablauf der Artikelbuchung Es gibt eine Firma → Artikelgenre auswählen → Sie können einen Artikel veröffentlichen Es ist ein Fluss geworden. Auf dieser Grundlage enthält der Vorher-Block die folgende Beschreibung, da ** Unternehmen und Genres vorhanden sein müssen **, um Artikel veröffentlichen zu können.

Der Rest ist einfach.

  1. Welches Unternehmen hat den Artikel veröffentlicht? 2. Welches Genre des Artikels? Ersetzen Sie @ article.company_id bzw. @ article.genre_id.
  2. Wenn alle Daten enthalten sind, 2. Wenn nicht alle Daten enthalten sind, testen Sie einfach separat nach Kontext!

③spec/models/article_spec.rb


RSpec.describe Article, type: :model do

  describe "Artikeltest" do
    before do
      #Es gibt eine Firma → Artikelgenre auswählen → Sie können einen Artikel veröffentlichen
      @company = FactoryBot.create(:company)
      @genre = FactoryBot.create(:genre)
      @article = FactoryBot.build(:article)
    end

    #Artikelerstellung
    context "Wenn alle Daten enthalten sind" do
      it "Alle werden eingegeben, damit sie gespeichert werden" do
        @article.company_id = @company.id
        @article.genre_id = @genre.id
        expect(@article.save).to be true
      end
    end

    context "Wenn nicht alle Daten enthalten sind" do
      it "Nicht gespeichert, da nicht alle eingegeben wurden" do
        @article.company_id = @company.id
        @article.genre_id = @genre.id
        @article.title = ""
        @article.body = ""
        expect(@article.save).to be false
      end
    end
  end

Damit ist der Modelltest abgeschlossen! Es gibt auch eine Modellspezifikation des Nachrichtenmodells, die ich jedoch weglassen werde, da die Anzahl der Elemente gering ist. Bei Interesse wenden Sie sich bitte an GitHub.

Am Ende

Dieses Mal haben wir die Modelltests und Modellspezifikationen zusammengefasst, die die Kernteile der Anwendung bilden. Modellspezifikationen sind ebenfalls wichtig, aber die wichtigsten sind die beim nächsten Mal beschriebenen Systemspezifikationen. Testen Sie das Verhalten in einem echten Browser, z. B. wenn ein Benutzer Meine Seite bearbeitet oder einen DM an ein Unternehmen sendet. Es gab viele Punkte zu stolpern. Vielleicht bin ich der einzige: Denken: Ich möchte es auf leicht verständliche Weise zusammenfassen, also hoffe ich, dass Sie es beim nächsten Mal wieder sehen. Danke, dass du bis zum Ende zugesehen hast.

** 2020.09.28 Die Ausgabe der Systemspezifikationen wurde veröffentlicht. Siehe hier. ** **.

Referenzartikel

https://qiita.com/jnchito/items/2a5d3e15761fd413657a https://qiita.com/jnchito/items/42193d066bd61c740612 https://qiita.com/jnchito/items/2e79a1abe7cd8214caa5

Recommended Posts

[1st] RSpec-Anfänger haben versucht, Model Spec als Anfänger zu schreiben
[3.] RSpec-Anfänger haben versucht, SystemSpec als Anfänger zu schreiben (endgültige Ausgabe)
[2.] RSpec-Anfänger haben SystemSpec als Anfänger geschrieben (Numa Edition)
Rails-Anfänger haben versucht, mit RSpec zu beginnen
So schreiben Sie ein benutzerorientiertes Programm (1)
Ich habe versucht, Code wie eine Typdeklaration in Ruby zu schreiben
[R Spec on Rails] So schreiben Sie Testcode für Anfänger von Anfängern
Java-Anfänger haben versucht, mit Spring Boot eine einfache Webanwendung zu erstellen
Ich möchte ein schönes build.gradle schreiben
[Basic] So schreiben Sie ein Dockerfile Selbstlernend ②
[Einführung in Java] So schreiben Sie ein Java-Programm
Ich möchte einen Unit Test schreiben!
[Java] Anfänger wollen Dating machen. 1
[SpringBoot] So schreiben Sie einen Controller-Test
Schnelle Anfänger versuchten, Mikrowellenlogik zu implementieren!
Stellen Sie sich RxJava als eine Bibliothek vor, die das Schreiben von asynchroner Verarbeitung erleichtert
[Azure] Ich habe versucht, eine Java-App für die Erstellung von kostenlosen Web-Apps zu erstellen. [Anfänger]
Schreiben Sie beim Definieren einer Klasse sowohl formatTo als auch toString (Verwendung von Formattable).