rails、minitestでモデルのバリデーションをする

railsでテストといえばRSpecが主流ですが、個人的にはminitestの方がわかりやすくて好き。

ということで、minitestでモデルのバリデーションをした時のメモ。



テストするモデル

SEIYUやマツモトキヨシなのどの小売業者が販売しているプライベートブランドをテストする。

小売業者 :SalesCompanyモデル, プライベートブランド :ProductBrandモデル

class SalesCompany < ApplicationRecord
  has_many :product_brands, dependent: :destroy

  # validates
  validates :sales_company_name, presence: true, uniqueness: true
end
class ProductBrand < ApplicationRecord
  belongs_to :sales_company

  # validates
  validates :product_brand_name, presence: true, uniqueness: true
end





テストコードをかく

minitestはrailsに標準でついているので、特段何かをする必要はない。

モデルを作れば自動でtestディレクトリ配下にテストのモデルとfixturesも作られます。

SalesCompanyモデルとProductBrandモデルのバリデーションはこんな感じになります。

# test/models/sales_company_test.rb
require 'test_helper'

class SalesCompanyTest < ActiveSupport::TestCase
  setup do
    @sales_company = sales_companies(:seiyu)
  end

  test "SalesCompanyは有効か" do
    assert @sales_company.valid?
  end

  test "sales_company_nameは必須" do
    @sales_company.sales_company_name = nil

    assert @sales_company.invalid?
    assert_includes @sales_company.errors[:sales_company_name], "can't be blank"
  end

  test "sales_company_nameはユニークでなければならない" do
    duplicate_sales_company = @sales_company.dup
    duplicate_sales_company.sales_company_name = @sales_company.sales_company_name
    assert_not duplicate_sales_company.valid?
  end
end





# test/models/product_brand_test.rb
require 'test_helper'

class ProductBrandTest < ActiveSupport::TestCase
  setup do
    sales_company = sales_companies(:seiyu)
    @product_brand = product_brands(:minasamano_osumitsuki)
  end


  test "ProductBrandは有効か" do
    assert @product_brand.valid?
  end

  test "product_brand_nameは必須" do
    @product_brand.product_brand_name = nil

    assert @product_brand.invalid?
    assert_includes @product_brand.errors[:product_brand_name], "can't be blank"
  end

  test "product_brand_nameはユニークでなければならない" do
    duplicate_product_brand = @product_brand.dup
    duplicate_product_brand.product_brand_name = @product_brand.product_brand_name
    assert_not duplicate_product_brand.valid?
  end
end





fixtures

minitestのfixtureは直感的でわかりやすい。

使う場合は、sales_companies(:seiyu)みたいな感じで使うことができる。

# sales_companies.yml
matsumotokiyoshi:
  sales_company_name: matsumotokiyoshi

seiyu:
  sales_company_name: seiyu

seven_eleven:
  sales_company_name: seven-eleven





# product_brands.yml
matsumotokiyoshi:
  sales_company_name: matsumotokiyoshi

seiyu:
  sales_company_name: seiyu

seven_eleven:
  sales_company_name: seven-eleven





See Also