假设我有这些模型:
class Person < ActiveRecord::Base
end
class Bob < Person
def name
'Bob'
end
end
class John < Person
def name
'John'
end
end
此代码效果很好:
# in controller:
@persons = Person.all
# in view:
- @persons.each do |person|
%p= person.name
但在我的spec文件中,当我写这样的东西时,我会收到错误:
it "display person names" do
Bob.create!
@person = Person.all.first
print @person.name # Error: undefined method 'name' for #<Person:0x...>
end
但是这段代码很好用:
it "display person names" do
Bob.create!
@person = Bob.all.first
print @person.name
end
我做错了什么?
P.S。问题仅出在RSpec文件中。控制器中的相同代码运行良好。
更新:找到解决方案!我应该运行“rake db:migrate RAILS_ENV = test”(最后一次迁移“add_type_to_person”仅应用于开发数据库“)
答案 0 :(得分:0)
我们不知道您的架构或数据是什么样的。 (约翰和鲍勃是桌子?)
我不得不猜测,Person没有name属性,这就是第一次测试失败的原因。
由于我不知道你在这里要做什么,我不能再进一步建议 - 但最简单的解决方案是将name方法放在Person对象上。 (假设它是某种虚拟列,也许你可以从数据中抽象出来,这样你就不必在子类中定义它了。)
答案 1 :(得分:0)
我猜问题出在你的灯具里。我猜你的其中一个灯具在type
列中没有正确的值,而且偶然地,这一条记录恰好由Person.all.first
Bob.all
与Person.all
不同 - 第一个只返回type = "Bob"
的记录,第二个将返回所有记录。
通常在测试中使用.first
不是一个好主意。通常您不知道(不指定)排序顺序,因此返回的记录是随机的。
在这种情况下,请检查失败测试返回的记录的type
字段的值。我想会有一些线索。
答案 2 :(得分:0)
在运行测试之前,您可以确保测试数据库的模式与开发数据库中的模式匹配:
rake db:test:prepare
如果您使用rake spec
调用rspec,则会为您做好准备。