在我的模型中,我基于数据库记录动态创建一些方法:
class Job < ActiveRecord::Base
belongs_to :job_status
# Adds #requisition?, #open?, #paused?, #closed?
class_eval do
JobStatus.all.each do |status|
unless method_defined? "#{status.name.downcase}?"
define_method("#{status.name.downcase}?") do
job_status_id == status.id
end
end
end
end
end
class JobStatus < ActiveRecord::Base
has_many :jobs
end
job_statuses
表包含一些种子数据,因此不会经常更改,但是如果我需要添加新状态,我不必添加更多代码来获取布尔方法新的状态。
但是,我不确定如何测试这些方法,因为当rspec启动时job_statuses
表显然是空的,并且在创建JobStatus
对象时,Job
被初始化,但由于还没有对象存在,它不会创建任何方法,并且我的测试失败,因为这些方法不存在。
请注意,我正在使用sppec&amp;保护,并使用数据库清理器与截断策略(根据Railscast #257,因为我使用Selenium),所以这可能使问题复杂化。
答案 0 :(得分:0)
我想出的解决方案是将运行时方法的创建抽象到库文件中,然后在我的测试文件中,在每次测试之前删除并重新声明我的类,然后重新加载实际的类(和蓝图)。套房结束:
describe AssociationPredicate do
before(:all) do
["Continuous", "Standard"].each { |type| JobType.create!(:job_type => type) }
["Requisition", "Open", "Paused", "Closed"].each { |status| JobStatus.create!(:job_status => status) }
end
after(:all) do
DatabaseCleaner.clean_with :truncation, :only => %w( job_types job_statuses )
# Reload Job model to remove changes
Object.send(:remove_const, 'Job')
load 'job.rb'
load 'support/blueprints.rb'
end
before(:each) do
Object.send(:remove_const, 'Job')
# Redefine Job model for testing purposes
class Job < ActiveRecord::Base
belongs_to :job_type
belongs_to :job_status
has_many :job_applications
end
end
it "should add methods when included" do
Job.send(:association_predicate, :job_type)
job.should respond_to(:continuous?)
job.should respond_to(:standard?)
end
end
这样,我为每个测试创建一个基本类,必要时添加运行时方法,并在完成后返回实际的类。
答案 1 :(得分:0)