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
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!