In Rspec, I want to take advantage of using super()
to call a defined let
block if it exists or set a new value if it hasn't, I want to use this within a shared_example
group but I just can't find how to do this.
I've tried checking if @some_let
exists, I've tried checking if a super method of :some_let
is owned by the kernel
or not and none of them provide anything useful; I can't access instance_methods
or instance_method
because Rspec won't let me and searching the internet for a method hasn't revealed an answer.
I want to be able to do something like this:
shared_examples 'a shared example' do
let(:some_let) { let_exists?(:some_let) ? super() : some_new_value }
end
is there a method like let_exists?
or something to that effect?
Assuming that you call let
before including the shared examples, this would work:
shared_examples 'a shared example' do
let(:some) { 'fallback value' } unless method_defined?(:some)
end
describe 'with let' do
let(:some) { 'explicit value' }
include_examples 'a shared example'
it { expect(some).to eq('explicit value') }
end
describe 'without let' do
include_examples 'a shared example'
it { expect(some).to eq('fallback value') }
end
method_defined?
checks if a method called some
has already been defined in the current context. If not, the method is defined to provide a default value.
Another (usually easier) approach is to always define a default value and to provide the explicit value after including the shared examples: (thus overwriting the default value)
shared_examples 'a shared example' do
let(:some) { 'default value' }
end
describe 'with let' do
include_examples 'a shared example' # <- order is
let(:some) { 'explicit value' } # important
it { expect(some).to eq('explicit value') }
end
describe 'without let' do
include_examples 'a shared example'
it { expect(some).to eq('default value') }
end