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.

Reply via email to