On Monday, April 14, 2014 6:27:18 AM UTC-7, Maurizio De Santis wrote:
>
> 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 :)
>
You can also do:
describe Hello do
attr_accessor :a, :b, :c
before(:all) do
self.a = 'a'
self.b = 'b'
self.c = 'c'
end
end
Or, if you don't mutate the values, you can just do:
describe Hello do
a = 'a'
b = 'b'
c = 'c'
end
...since local variables can be accessed from within any hooks or examples
since blocks are closures.
HTH,
Myron
--
You received this message because you are subscribed to the Google Groups
"rspec" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/rspec/b343148d-ee44-4902-8dfc-6a4ef7fb939e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.