【rails】保存が失敗するケースのテストをする

※本サイトで紹介している商品・サービス等の外部リンクには、アフィリエイト広告が含まれる場合があります。

保存が失敗するケースも追加してテストする

前回までで「保存が成功するケース」のテストをしてきた

今回は「保存が失敗するケース」のテストをする


テストの流れ

今回もこちらの流れに沿ってテストをしていく

  1. 確認したいことを決める
  2. ダミーデータを作成する
  3. ダミーデータで「1.確認したいこと」が起こるか確認する

確認したいこと

「タイトルが一文字の場合」保存ができないことを確認したい

※Validationではvalidates :title, length: { minimum: 2, maximum: 100 }(2文字以上)になっている


ダミーデータを作成する

前回のコード↓を書き換えていく

RSpec.describe Article, type: :model do
  context 'タイトルと内容が入力されている場合' do
    let!(:user) do
      user = User.create!({
        email: 'test@example.com',
        password: 'password'
      })
    end

    let!(:article) do
      article = user.articles.build({
        title: Faker::Lorem.characters(number: 10),
        content: Faker::Lorem.characters(number: 300)
      })
    end

    it '記事を保存できる' do
      expect(article).to be_valid
    end
  end
end

contextで前提条件を書く

  context 'タイトルの文字が一文字の場合' do
    let!(:article) do
      article = user.articles.create({
        title: Faker::Lorem.characters(number: 1),
        content: Faker::Lorem.characters(number: 300)
      })
    end

    it '記事を保存できない' do
      expect(article.errors.messages[:title][0]).to eq('は2文字以上で入力してください')
    end
  end
  1. 「タイトルの文字が一文字の場合」なので、title: Faker::Lorem.characters(number: 1)としておく
  2. 記事を保存できないとき、articleのエラーメッセージが返ってくる
  3. エラーメッセージの配列の最初[0]が「は2文字以上で入力してください」なので、それとイコール(eq)かを確認する
  4. このエラーメッセージを出すには、buildじゃなくてcreateじゃないといけない
  5. 今回はarticle = user.articles.createとしている

エラーメッセージが出るのは、createsaveをした瞬間のみ


let!(:user)を宣言する場所

let!(:user)は2つのcontextどちらにも適用したいので、頭に持ってくる

RSpec.describe Article, type: :model do
  let!(:user) do
    user = User.create!({
      email: 'test@example.com',
      password: 'password'
    })
  end

  context 'タイトルと内容が入力されている場合' do
  #中略
  end

  context 'タイトルの文字が一文字の場合' do
  #中略
  end
end

出来上がったコード

確認したいこと
  • 「タイトルと内容が入力されている場合」に保存できるか
  • 「タイトルの文字が一文字の場合」に保存に失敗するか
RSpec.describe Article, type: :model do
  let!(:user) do
    user = User.create!({
      email: 'test@example.com',
      password: 'password'
    })
  end

  context 'タイトルと内容が入力されている場合' do
    let!(:article) do
      article = user.articles.build({
        title: Faker::Lorem.characters(number: 10),
        content: Faker::Lorem.characters(number: 300)
      })
    end
    it '記事を保存できる' do
      expect(article).to be_valid
    end
  end

  context 'タイトルの文字が一文字の場合' do
    let!(:article) do
      article = user.articles.create({
        title: Faker::Lorem.characters(number: 1),
        content: Faker::Lorem.characters(number: 300)
      })
    end
    it '記事を保存できない' do
      expect(article.errors.messages[:title][0]).to eq('は2文字以上で入力してください')
    end
  end
end


コードを実行してみる

ターミナルでこれまでと同様に実行する

bundle exec rspec spec/models/article_spec.rb

テストは2つとも成功!!

#DAY13