thoughtbot / shoulda-matchers

Simple one-liner tests for common Rails functionality
https://matchers.shoulda.io
MIT License
3.5k stars 911 forks source link

What Pieces of ActiveModel/ActiveRecord need to be present for shoulda to appear? #1628

Closed dlinch closed 4 months ago

dlinch commented 4 months ago

Description

I have a form object in my codebase that I am trying to use shoulda matches on. The base class has:

  included do
    extend ActiveModel::Callbacks
    include ActiveModel::Model
    include ActiveModel::Validations::Callbacks
    include ActiveModel::Attributes
    # ...

I am getting the follow error:

NoMethodError:
       undefined method `validate_presence_of' for #<RSpec::ExampleGroups::<MY CLASSES HERE>

I added the gem to my gemfile, and put the initialization inside a support class.

# spec/support/shoulda.rb

require "shoulda/matchers"

Shoulda::Matchers.configure do |config|
  puts "I AM HERE"
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end

The puts command successfully prints out when I run my test. Here is the spec:

require "rails_helper"

RSpec.describe MyFormClass do
  # .. test setup

  let(:subject) { described_class.new(**kwargs) }

  describe "#validations" do
    it { should validate_presence_of(:my_attribute) }
  end
end

The documentation makes it seem like you can run the matches anywhere but I'm worried there may some kind of hooks for some ActiveRecord/ActiveModel classes that I don't happen to have included here, and they are not made available to the project at large unless the object being tested is in the right namespace, I've never actually tried to use these on anything other than my model specs before today.

Reproduction Steps

You can easily create some base class including the above libraries, run a test against it and see it not run.

Expected behavior

I expected the matchers to be available.

Actual behavior

They were not available and threw a NoMethodError

System configuration

shoulda_matchers version: 6.2.0 rails version: 7.0.7.2 ruby version: 3.2.2

dlinch commented 4 months ago

Quick update, I was able to get this working when I head directly into the Rspec.configure block:

config.include(Shoulda::Matchers::ActiveModel)
config.include(Shoulda::Matchers::ActiveRecord)

I picked it up from this issue, but that's really old, like Rails 5 old. Some other context is that this is in a Rails engine rather than a regular plain ol' Rails project, so not sure if some of the loading is slightly different because of that.

dlinch commented 4 months ago

Ugh, I'm a dummy. I didn't read this part of the [documentation.]https://github.com/thoughtbot/shoulda-matchers?tab=readme-ov-file#availability-of-rspec-matchers-in-example-groups)

My bad, closing now!