我经常发现我希望能够使用Rails控制台中的测试夹具查找器(例如users(:david)
)。是否有一个特定的Rails模块,我可以在控制台提示符下加载,或者我可以安装的gem,这些可以使这些模块可用吗?
我对谷歌甲骨文的疑问没有改变,所以我没有屏住呼吸,但我希望有人知道这个秘密并愿意分享。
答案 0 :(得分:7)
自己想出来。 适用于IRB和Pry。只需将以下行添加到我的.irbrc(和/或.pryrc)文件中。
require 'active_record/fixtures'
def method_missing(method_name, *args, &block)
if fixture_names.include?(method_name)
method_name.to_s.singularize.titleize.constantize.find(fixture_id(args[0]))
else
super
end
end
def fixture_id(label)
ActiveRecord::FixtureSet.identify(label)
end
def fixture_names
Dir["#{Rails.root}/test/fixtures/*.yml"].map { |filename| filename.match(/\/([^\/]+)\.yml/)[1].to_sym }
end
现在,假设有一个test/fixtures/users.yml
文件并且它包含一个名为diane:
的夹具,那么来自Rails控制台的users(:diane)
成功返回该用户。
原始问题的m_x answer有助于达到这一点。
答案 1 :(得分:2)
我希望我能加入Jon Garvin的优秀答案。这就像他的版本,但不使用method_missing(这在全局上下文中有点可怕,并且不允许选项卡完成)。此外,它会一直等到你在加载灯具之前从irb调用load_fixtures。
将此插入.irbrc或从此处粘贴。
# Loads all fixtures, then defines the Rails fixture helpers.
# For example: users(:jon) will load the jon fixture from fixtures/users.yml
def load_fixtures
require 'active_record/fixtures'
Dir["#{Rails.root}/{test,spec}"].each do |dir|
Dir["#{dir}/fixtures/*.yml"].map { |filename| filename.match(/\/([^\/]+)\.yml/)[1].to_sym }.each do |name|
ActiveRecord::FixtureSet.create_fixtures('spec/fixtures', name)
define_method(name) { |*args|
name.to_s.singularize.titleize.constantize.find(ActiveRecord::FixtureSet.identify(args[0]))
}
end
end
end
使用示例:
$ irb
irb(main):001:0> load_fixtures
=> ["oweto/spec"]
irb(main):002:0> users(:chuy)
=> #<User id: 242462757, email: "chuy@example.com", password_digest: ...>
答案 2 :(得分:1)
有趣的问题。
不知道这是否有帮助,但加载灯具的实际逻辑似乎位于active_record/fixtures.rb - 尤其要看ActiveRecord::TestFixtures::ClassMethods#fixtures
这是你通常在{{1}内调用的宏子类。
逻辑似乎很好地包含在TestCase
模块中,所以也许您可以尝试滚动自己的包含该模块的类并在控制台中需要它。 (看起来你需要在访问灯具之前实例化这个类,因为模块生成的方法是实例方法)
答案 3 :(得分:0)
我们使用FactoryGirl来发挥效果。
如果你能够使用factory_girl,它有一些很好的功能混合特性和工厂继承。对于工厂女孩来说,通过规格访问它并通过控制台访问它非常相似。
require 'factory_girl'
user = FactoryGirl.create(:user)
如果使用bundler,您可以为包含工厂女孩的开发和测试环境创建一个gem组,然后在开发中使用控制台时不需要它。
group :development, :test do
gem 'factory_girl'
end
答案 4 :(得分:0)
另一个答案是不完整的,您需要告诉FactoryGirl加载定义:
require 'factory_girl'
FactoryGirl.find_definitions
user = FactoryGirl.create(:user)
有关详细信息,请参阅docs。