Hello everyone,
firstly I'm sorry for my poor english, I hope I'll manage to be clear; don't hesitate to ask for clarifications if I will not.
In my tests this is a common pattern:
describe Hello do
def a
@a ||= 'a'
end
def b
@b ||= 'b'
end
def c
@c ||= 'c'
end
let(:d) { 'd' }
let(:e) { 'e' }
let(:f) { 'f' }
before(:all) do
a
b
c
end
end
I have to use def ... for the methods used inside before(:all), due to the problems described in
https://github.com/rspec/rspec-core/issues/500 .
My problem with it is that I don't like its readability: it isn't DRY and it doesn't express what I intend.
My ideal pattern would be like this:
describe Hello do
let(:a) { 'a' }
let(:b) { 'b' }
let(:c) { 'c' }
let(:d) { 'd' }
let(:e) { 'e' }
let(:f) { 'f' }
before(:all) do
a
b
c
end
end
But I know it is utopian, since the problem described in the issue above.
So I would like to have your opinions about something like (notice set instead of let):
describe Hello do
set(:a) { 'a' }
set(:b) { 'b' }
set(:c) { 'c' }
let(:d) { 'd' }
let(:e) { 'e' }
let(:f) { 'f' }
before(:all) do
a
b
c
end
end
Or (maybe even better) something like:
describe Hello do
let(:a, :all) { 'a' }
let(:b, :all) { 'b' }
let(:c, :all) { 'c' }
let(:d) { 'd' }
let(:e) { 'e' }
let(:f) { 'f' }
before(:all) do
a
b
c
end
end
I think it is better with "let, argument indicating using in before(:all)" because it is unnecessary to create another method, and it is more "explicit" about what it's doing.
At the moment, I'm using the following (as poor as effective) implementation:
module RSpecSet
def set(name, &block)
instance_variable_name = :"@#{name}"
define_method(name) do
return instance_variable_get instance_variable_name if instance_variable_defined? instance_variable_name
instance_variable_set instance_variable_name, block.call
end
end
def set!(name, &block)
define_method(name) { instance_variable_set :"@#{name}", block.call }
end
end
Rspec.config { |c| c.extend RSpecSet }
Where set memoizes the result into an instance variable, while set! does not.
Looking at rspec-core-3.0.0.beta2/lib/rspec/core/memoized_helpers.rb , where let and let! are implemented, I guess that an implementation more similar to it would be more appropriate, but I haven't figured out it yet.
What do you think about it? Am I the only with this need? Are you happy with the "if not in before_all let else def" approach? Do you have ideas in order to improve my RSpecSet?
Thank you all and long live to RSpec :)