環境
Rails 6.1.3.1
ruby 2.7.1
mysql Ver 8.0.26
shoulda-matchers
というGemを使ってテストを書くとき、下記のエラーでテストが通らない。
it { is_expected.to validate_uniqueness_of(:number) }
Expected Employee to validate that :number is unique, but this could not
be proved.
After taking the given Employee, whose :number is ‹0›, and saving it
as the existing record, then making a new Employee and setting its
:number to ‹0› as well, the matcher expected the new Employee to be
invalid, but it was valid instead.
解決法
This matcher works a bit differently than other matchers. As noted before, it will create an instance of your model if one doesn't already exist. Sometimes this step fails, especially if you have database-level restrictions on any attributes other than the one which is unique. In this case, the solution is to populate these attributes with values before you call
validate_uniqueness_of
.
ドキュメントにも書いてあるが、validate_uniqueness_of
はモデルのインスタンスがまだ存在しない場合インスタンスを作成する。このときに今回でいうとnumber
が一意でなかったためテストが落ちてしまった。
Factoryでインスタンスを生成しておくとテストが通るようになる。
subject { build(:employee) }
it { is_expected.to validate_uniqueness_of(:number).ignoring_case_sensitivity }