ruby-on-railsrspecshouldareform

Shoulda matcher `validate_length_of` in RSpec with Reform form


I'm setting up specs for my forms (using Reform gem) with RSpec and Shoulda Matchers gems. I'cant figure out why I'm having validation issues.

My actual configurations :

  ruby '2.5.1'
  gem 'rails', '~> 5.2.0'
  gem 'rspec-rails', '~> 3.8'
  gem 'shoulda-matchers', '~> 4.0'
  gem 'reform-rails', '~> 0.1'

I've already tried different sorts of length validations in my form. But nothing make things much better.

Here is the minimal form used for testing :

# frozen_string_literal: true

class UserForm < Reform::Form
  # == Properties  ==========================================================
  property :nickname


  # == Validations ==========================================================
  validates :nickname, presence: true, length: { minimum: 3, maximum: 100 } 
end

Here is the spec :

# frozen_string_literal: true

RSpec.describe UserForm, type: :model do
  subject { described_class.new(User.new) }

  it { is_expected.to validate_presence_of :nickname }
  it { is_expected.to validate_length_of(:nickname).is_at_least(3).is_at_most(100) }
end

Note that the validate_presence_of matcher works perfectly.

I'm having as RSpec output :

  1) UserForm should validate that the length of :nickname is between 3 and 100
     Failure/Error: it { is_expected.to validate_length_of(:nickname).is_at_least(3).is_at_most(100) }

       Expected UserForm to validate that the length of :nickname is between
       3 and 100, but this could not be proved.
         After setting :nickname to ‹"xxx"›, the matcher expected the
         UserForm to be valid, but it was invalid instead, producing these
         validation errors:

         * nickname: ["is too short (at least 3 characters)"]

I'm obviously excepting to make these sorts of validations working.

I hope I can find help here :)


Solution

  • Reform is known not to work with shoulda-matchers. Basically, all of the model matchers in shoulda-matchers work by:

    However, Reform doesn't work this way; you don't set properties on the form object individually and then call valid?, you call validate with the properties you want to set on the form object, and then those properties are validated in the process of being set. So that's likely why you're getting this error — because shoulda-matchers is trying to manually set the properties, and then validate is blowing them away.

    Unfortunately, there's not a way to get shoulda-matchers to work with Reform without writing some kind of adapter. We don't plan on adding this to the gem any time soon but we will take a PR! Other than this, apparently the Reform team was talking about making some RSpec matchers in the spirit of shoulda-matchers, but I'm not sure how much progress has been made there, if any.

    Sorry I couldn't be more helpful :/