I have this:
def valid_attributes
{ :email => "some_#{rand(9999)}@thing.com" }
end
For Rspec testing right? But I would like to do something like this:
def valid_attributes
static user_id = 0
user_id += 1
{ :email => "some_#{user_id}@thing.com" }
end
I don't want user_id
to be accessible from anywhere but that method,
is this possible with Ruby?
This is a closure case. Try this
lambda { user_id = 0 self.class.send(:define_method, :valid_attributes) do user_id += 1 { :email => "some_#{user_id}@thing.com" } end }.call
Wrapping everything in lambda allows the variables defined within lambda to only exist in the scope. You can add other methods also. Good luck!
This answer is a little larger in scope than your question, but I think it gets at the root of what you're trying to do, and will be the easiest and most maintainable.
I think what you're really looking for here is factories. Try using something like factory_girl, which will make a lot of testing much easier.
First, you'd set up a factory to create whatever type of object it is you're testing, and use a sequence for the email attribute:
FactoryGirl.define do
factory :model do
sequence(:email) {|n| "person#{n}@example.com" }
# include whatever else is required to make your model valid
end
end
Then, when you need valid attributes, you can use
Factory.attributes_for(:model)
You can also use Factory.create
and Factory.build
to create saved and unsaved instances of the model.
There's explanation of a lot more of the features in the getting started document, as well as instructions on how to add factories to your project.
You can use a closure:
def validator_factory
user_id = 0
lambda do
user_id += 1
{ :email => "some_#{user_id}@thing.com" }
end
end
valid_attributes = validator_factory
valid_attributes.call #=> {:email=>"[email protected]"}
valid_attributes.call #=> {:email=>"[email protected]"}
This way user_id
won't be accessible outside.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With