3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

RSpec shoulda-matchersの使い方

Last updated at Posted at 2023-03-17

はじめに

RSpecにおいてshoulda-matchersというgemがあります。
とても便利で、RSpecを簡潔に書く事ができます。

環境

rails (7.0.4)
rspec-rails (6.0.1)
shoulda-matchers (5.3.0)

shoulda-matchersとは

RSpecと互換性があり、RSpecのコードを簡潔に記述する事ができるgemです。
主にモデルのバリデーションで使用します。
参考:Shoulda Matchers

導入

Gemに追加

Gemfile
  gem "shoulda-matchers"

インストール

ターミナル
bundle install

spec/rails_helper.rbに以下を記述(もしくはsupportファイル)

spec/rails_helper.rb
RSpec.configure do |config|
#...省略
#...
end

#以下追記
Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end

使い方(使用頻度の高いものを抜粋)

よく使うバリデーションや設定を書いていきます。
詳しく知りたい方はこちらのREADMEをご覧ください。

presence

User.rb
class User < ApplicationRecord
    validates :email, presence: true
end
spec/models/user_sepc.rb
require 'rails_helper'

RSpec.describe User, type: :model do
    it { is_expected.to validate_presence_of :name }
end

uniqueness

User.rb
class User < ApplicationRecord
    validates :name, uniqueness: true
end
spec/models/user_sepc.rb
require 'rails_helper'

RSpec.describe User, type: :model do
    it { should validate_uniqueness_of(:email) }
end

※Deviseを使用していたり、DBに保存する前にdowncaseなどで加工しているとエラーが発生します。

その場合は以下のようにします。 参考

spec/models/user_sepc.rb
require 'rails_helper'

RSpec.describe User, type: :model do
    it { should validate_uniqueness_of(:email).ignoring_case_sensitivity  }
end

length

User.rb
class User < ApplicationRecord
    validates :name, length: { minimum: 3 }
    validates :name, length: { maximum: 6 }
    validates :password, length { in: 6..10 }
end
spec/models/user_sepc.rb
require 'rails_helper'

RSpec.describe User, type: :model do
    it { is_expected.to validate_length_of(:name).is_at_least(3) }
    it { is_expected.to validate_length_of(:name).is_at_most(6) }
    it do
      is_expected.to validate_length_of(:password).
        is_at_least(6).
        is_at_most(10)
    end
end

has_secure_password

User.rb
class User < ApplicationRecord
    has_secure_password
    has_secure_password :reset_password
end
spec/models/user_sepc.rb
require 'rails_helper'

RSpec.describe User, type: :model do
    it { is_expected.to have_secure_password }
    it { is_expected.to have_secure_password(:reset_password) }
end

belongs_to

Person.rb
class Person < ApplicationRecord
    belongs_to :organization
end
spec/models/person_sepc.rb
require 'rails_helper'

RSpec.describe Person, type: :model do
    it { is_expected.to belong_to(:organization) }
end

has_many

User.rb
class User < ApplicationRecord
    has_many :shirts, -> { order('color') }
end
spec/models/user_sepc.rb
require 'rails_helper'

RSpec.describe User, type: :model do
    it { is_expected.to have_many(:shirts).order('color') }
end

dependent

User.rb
class User < ApplicationRecord
    has_many :tweets, dependent: :destroy
end
spec/models/user_sepc.rb
require 'rails_helper'

RSpec.describe User, type: :model do
    it { is_expected.to have_many(:tweets).dependent(:destroy) }
end

through

Person.rb
class Person < ApplicationRecord
    has_many :acquaintances, through: :friends
end
spec/models/person_sepc.rb
require 'rails_helper'

RSpec.describe Person, type: :model do
    it { is_expected.to have_many(:acquaintances).through(:friends) }
end

source

Person.rb
class Person < ApplicationRecord
    has_many :job_offers, through: :friends, source: :opportunities
end
spec/models/person_sepc.rb
require 'rails_helper'

RSpec.describe Person, type: :model do
    it do
      should have_many(:job_offers).
        through(:friends).
        source(:opportunities)
    end
end

has_one

Tweet.rb
class Tweet < ApplicationRecord
    has_one :image
end
spec/models/tweet_sepc.rb
require 'rails_helper'

RSpec.describe Tweet, type: :model do
    it { is_expected.to have_one_attached(:image) }
end

has_many

Tweet.rb
class Tweet < ApplicationRecord
    has_one :images
end
spec/models/tweet_sepc.rb
require 'rails_helper'

RSpec.describe Tweet, type: :model do
    it { is_expected.to have_many_attached(:images) }
end

参考サイト

Shoulda Matchers

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?