我有这个:
def valid_attributes
{ :email => "some_#{rand(9999)}@thing.com" }
end
对于Rspec测试吧?但我想做这样的事情:
def valid_attributes
static user_id = 0
user_id += 1
{ :email => "some_#{user_id}@thing.com" }
end
我不希望{@ 1}}可以从任何地方访问,但该方法, 这可能与Ruby有关吗?
答案 0 :(得分:8)
这是一个封闭案例。试试这个
lambda { user_id = 0 self.class.send(:define_method, :valid_attributes) do user_id += 1 { :email => "some_#{user_id}@thing.com" } end }.call
在lambda中包装所有内容允许lambda中定义的变量仅存在于范围内。您也可以添加其他方法。祝你好运!
答案 1 :(得分:6)
这个答案的范围比你的问题要大一些,但我认为它是你想要做的事情的根源,并且将是最容易和最易维护的。
我认为你真正想要的是工厂。尝试使用类似factory_girl的内容,这将使大量测试变得更加容易。
首先,您要设置一个工厂来创建您正在测试的任何类型的对象,并使用序列作为电子邮件属性:
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
然后,当您需要有效属性时,可以使用
Factory.attributes_for(:model)
您还可以使用Factory.create
和Factory.build
来创建模型的已保存和未保存的实例。
有getting started document中更多功能的说明,以及如何将工厂添加到项目中的说明。
答案 2 :(得分:5)
您可以使用闭包:
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=>"some_1@thing.com"}
valid_attributes.call #=> {:email=>"some_2@thing.com"}
这种方式user_id
无法在外部访问。
答案 3 :(得分:4)
我使用了一个实例变量:
def valid_attributes
@user_id ||= 0
@user_id += 1
{ :email => "some_#{@user_id}@thing.com" }
end
答案 4 :(得分:0)
Ruby唯一的变量是局部变量,实例变量,类变量和全局变量。它们都不适合你所追求的目标。
您可能需要的是存储user_id的单例,并且每次都会为您提供一个新的ID号。否则,您的代码将不是线程安全的。