I was looking model generic custom validations. I ended up with something that I thought could be shared, including generic tests.
First, set up the concern app/models/concern/my_concern.rb
.
Please note that we don't define the validate_my_field
into a ClassMethods
module.
module MyConcern
extend ActiveSupport::Concern
included do
validate :my_field, :validate_my_field
end
private
def validate_my_field
...
end
end
Include concern into your model app/models/my_model.rb
class MyModel < ActiveRecord::Base
include MyConcern
end
Load concerns shared examples in spec/support/rails_helper
:
...
Dir[Rails.root.join('spec/concerns/**/*.rb')].each { |f| require f }
...
Create concern shared examples spec/concerns/models/my_field_concern_spec.rb
:
RSpec.shared_examples_for 'my_field_concern' do
let(:model) { described_class } # the class that includes the concern
it 'has a valid my_field' do
instance = build(model.to_s.underscore.to_sym, my_field: …)
expect(instance).not_to be_valid
…
end
end
Then finally call shared examples into your model spec spec/models/my_model_spec.rb
:
require 'rails_helper'
RSpec.describe MyModel do
include_examples 'my_field_concern'
it_behaves_like 'my_field_concern'
end