Assert Method is Used? (ActiveRecord Scopes)

Long time lurker… I fully admit: This is kind of an exceptional use case for rspec. I’m teaching a course which uses Rails, and as such I’ve got some tricky things I’d like to test for.

How can I expect that a method calls where, or calls it indirectly through something like a scope or method chaining?

Here’s what I’ve got:

# activerecord_praice_spec.rb

before(:each) do
        expect(Customer).to receive(:where).and_call_original
end

#...
specify 'with valid email (email addr contains "@") (HINT: look up SQL LIKE operator)' do
  check Customer.with_valid_email, [1,2,4,5,7,8,10,11,12,13,14,15,17,18,19,20,23,26,29,30]
end

(check simply does some formatting to clarify which records should/shouldn’t be in the result).

# activerecord_practice.rb

class Customer < ActiveRecord:Base
  def self.with_valid_email
      where( ....)
   end

If the method body always starts with where, then the expectation works fine. This all makes sense to me.

However, I would like to support (and even encourage) students to write scopes, such that this might be a valid function:

  def self.with_valid_email_and_born_before_1980
    born_before('1980-01-01').and(valid_email)
  end

born_before and valid_email are defined as scopes. Inside the scope, where is still used. So ideally what I am looking for is "somewhere in this callstack where is called. To make matters a little complex, the names of the scopes would be up to students.

Like I said, this one’s stumped me a bit because I’ve never had a use quite like this in a production codebase (thankfully!).

Appreciate any ideas!