初投稿です。
RSpecでuserのmodel specを書いている時に生じた問題についてまとめてみました。
#実行環境
- Rails 6.1.3.1
- Ruby 3.0.0p0
- RSpec 3.10
- FactoryBot 6.2.0
- MySQL 8.0.23
#問題
###Userモデル
app/models/user.rb
class User < ApplicationRecord
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: true
end
###userのファクトリ
spec/factories/users.rb
FactoryBot.define do
factory :user do
sequence(:name) { |n| "Example User#{n}" }
email { "user@example.com" }
end
end
###user_spec
spec/models/user_spec.rb
...
it "has unique email address" do
user1 = FactoryBot.create(:user, email: "user@example.com")
user2 = FactoryBot.build(:user, email: "user@example.com")
user2.email.upcase!
expect(user2).to be_invalid
end
...
同じ文字列のメールアドレスは大文字と小文字で区別しないというテストでREDにしたかったのですが、GREENになってしまいました。
#やってみたこと
spec/models/user_spec.rb
...
user2.email.upcase!
expect(user1.email).to eq "user@example.com"
expect(user2.email).to eq "USER@EXAMPLE.COM"
expect(user2).to be_invalid
end
user1とuser2のアドレスが正しく設定されているか確認してみましたが、どちらもGREENでした。
#解決
modelもテストコードも正しいとなるとデータベースに問題があるのかな?と思い調べてみると、
MySQLはデフォルトでcharの大文字小文字を区別しない
とのことでした。だからuniquness: { case_sensitive: false }が無しでもテストが通ってしまったようです。
おわり