Adding helpers for RSpec memoization
I thought initially it would be incredibly easy to add a wrapper method alongside existing let, let!, subject memoized helper methods in RSpec.
def current_user(&block)
u = yield
allow(User).to receive(:current_user).and_return(u)
end
describe 'stuff' do
let(:artist) { Fabricate(:artist) }
current_user { artist.user }
end
But I kept getting. `artist` is not available on an example group when the current user block was yielded. I had to dig into RSpec::Core to find how let is defined and came up with and ensure that artist and current_user were in the same scope when calling one another.
module CurrentUserHelpers
extend ActiveSupport::Concern
module ClassMethods
def current_user(&block)
raise "#current_usercalled without a block" if block.nil?
RSpec::Core::MemoizedHelpers.module_for(self).__send__(:define_method, :current_user, &block)
# Apply the memoization. The method has been defined in an ancestor
# module so we can use `super` here to get the value.
define_method(:current_user) do
u = __memoized.fetch_or_store(:current_user) do
block.arity == 1 ? super(RSpec.current_example, &nil) : super(&nil)
end
allow(User).to receive(:current_user).and_return(u)
u
end
end
def current_user!(&block)
current_user(&block)
before { current_user }
end
end
end