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!