I have the following code in one of my classes:
class Settings < ActiveRecord::Base
def self.current
@settings ||= Settings.where({ environment: Rails.env }).first_or_create!
end
end
The main behavior:
- It creates a new record on the first call.
- It returns the same result with subsequent calls.
- Resets ivar after each update, returning the first (and unique) record associated with the current environment in subsequent calls.
For this method, I have the following test:
describe Settings do
describe ".current" do
it "gets all settings for current environment" do
expect(Settings.current).to eq(Settings.where({ environment: 'test' }).first)
end
end
end
I don't like this because I don't really test memoization, so I stick to the approach of this question and I tried something like this:
describe ".current" do
it "gets all settings for current environment" do
expect(Settings).to receive(:where).with({ environment: 'test' }).once
2.times { Settings.current }
end
end
But this test returns the following error:
NoMethodError:
undefined method `first_or_create!' for nil:NilClass
So my question is: how can I test memoization for this method with RSpec?
UPDATE:
Finally, my approach is as follows:
describe Settings do
describe ".current" do
it "gets all settings for current environment" do
expect(described_class.current).to eq(described_class.where(environment: 'test').first)
end
it "memoizes the settings for current environment in subsequent calls" do
expect(described_class).to receive(:where).once.with(environment: 'test').and_call_original
2.times { described_class.current }
end
end
end