Rails 4 Minitest 测试虚拟属性
Rails 4 Minitest Testing Virtual Attributes
所以我有一个 class TimeBank,它正在更新,并且正在获取两个新的虚拟属性,它们将操纵另外两个现有属性(数据库列)。
class TimeBank < ActiveRecord::Base
# validations, consts, few other methods omitted for brevity
def date_worked
@date_worked ||= self.start.to_date
rescue
Date.current
end
def date_worked=(date_worked_val)
self.attributes['date_worked'] = date_worked_val
end
def hours_worked
@hours_worked ||= hours
rescue NoMethodError
nil
end
def hours_worked=(hours_worked_val)
self.attributes['hours_worked'] = hours_worked_val
end
def hours
if attributes["hours"]
read_attribute(:hours).to_f
else
((finish - start)/1.hour).to_f
end
rescue NoMethodError
0.0
end
# other methods omitted for brevity...
end
使用该应用程序时一切正常。当 运行 测试时,任何时候我实例化一个 TimeBank,我只得到上面 rescue
语句的结果,即 date_worked
的今天日期和 [=17] 的 0.0
=].二传手似乎没有反应,就像他们什么都不做(在测试中)。
我还定义了 setter 以使用 write_attribute(:date_worked, 'SOMEVAL')
,虽然它在应用程序中有效,但对于测试,我收到类似
的错误
ActiveModel::MissingAttributeError: can't write unknown attribute hours_worked'
app/models/time_bank.rb:110:in `hours_worked='
测试示例如下:
describe "virtual attributes test" do
subject { TimeBank.new({member: @gus, admin_id: @addy.id, date_worked: Date.yesterday, hours_worked: 2.5, time_type: "store_shift", approved: true}) }
it "tests setter callbacks" do
subject.date_worked.must_equal Date.yesterday
subject.hours_worked.must_equal 2.5
end
end
这两个断言总是失败,因为它们得到今天的日期和 0.0(getter 中指定的 "defaults")。如果我在测试之前立即在行上设置属性,它仍然没有效果。
我不确定我做错了什么。我想为这两个虚拟属性编写测试,但它们的值的任何设置似乎都没有效果。我不确定为什么它在测试中不起作用,但在应用程序中运行良好。相同的代码在应用程序控制器中按预期工作。谁能帮我理解为什么?
问题出在 setter 方法中。不需要为 self.attributes["virtual_attribute"]
赋值,而是需要设置并返回一个实例变量,如下所示:
def virtual_attribute=(virtual_attr_value)
@virtual_attribute = virtual_attr_value
end
所以对于我的示例,我需要:
def hours_worked=(hours_worked_val)
@hours_worked = hours_worked_val
end
应用程序和我在 minitest 中的 getter/setter 测试现在都按预期运行。
所以我有一个 class TimeBank,它正在更新,并且正在获取两个新的虚拟属性,它们将操纵另外两个现有属性(数据库列)。
class TimeBank < ActiveRecord::Base
# validations, consts, few other methods omitted for brevity
def date_worked
@date_worked ||= self.start.to_date
rescue
Date.current
end
def date_worked=(date_worked_val)
self.attributes['date_worked'] = date_worked_val
end
def hours_worked
@hours_worked ||= hours
rescue NoMethodError
nil
end
def hours_worked=(hours_worked_val)
self.attributes['hours_worked'] = hours_worked_val
end
def hours
if attributes["hours"]
read_attribute(:hours).to_f
else
((finish - start)/1.hour).to_f
end
rescue NoMethodError
0.0
end
# other methods omitted for brevity...
end
使用该应用程序时一切正常。当 运行 测试时,任何时候我实例化一个 TimeBank,我只得到上面 rescue
语句的结果,即 date_worked
的今天日期和 [=17] 的 0.0
=].二传手似乎没有反应,就像他们什么都不做(在测试中)。
我还定义了 setter 以使用 write_attribute(:date_worked, 'SOMEVAL')
,虽然它在应用程序中有效,但对于测试,我收到类似
ActiveModel::MissingAttributeError: can't write unknown attribute hours_worked'
app/models/time_bank.rb:110:in `hours_worked='
测试示例如下:
describe "virtual attributes test" do
subject { TimeBank.new({member: @gus, admin_id: @addy.id, date_worked: Date.yesterday, hours_worked: 2.5, time_type: "store_shift", approved: true}) }
it "tests setter callbacks" do
subject.date_worked.must_equal Date.yesterday
subject.hours_worked.must_equal 2.5
end
end
这两个断言总是失败,因为它们得到今天的日期和 0.0(getter 中指定的 "defaults")。如果我在测试之前立即在行上设置属性,它仍然没有效果。
我不确定我做错了什么。我想为这两个虚拟属性编写测试,但它们的值的任何设置似乎都没有效果。我不确定为什么它在测试中不起作用,但在应用程序中运行良好。相同的代码在应用程序控制器中按预期工作。谁能帮我理解为什么?
问题出在 setter 方法中。不需要为 self.attributes["virtual_attribute"]
赋值,而是需要设置并返回一个实例变量,如下所示:
def virtual_attribute=(virtual_attr_value)
@virtual_attribute = virtual_attr_value
end
所以对于我的示例,我需要:
def hours_worked=(hours_worked_val)
@hours_worked = hours_worked_val
end
应用程序和我在 minitest 中的 getter/setter 测试现在都按预期运行。