Rails 4 Minitest Testing Virtual Attributes

邮差的信 提交于 2020-01-17 05:38:22

问题


So I have a class TimeBank, and its being updated, and is getting two new virtual attributes which will manipulate two other existing attributes (DB columns).

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

Everything works fine when using the application. When running tests, any time I instantiate a TimeBank, I only get the results of the rescue statements above, namely, today's date for date_worked and 0.0 for hours_worked. The setters seem unresponsive, like they do nothing (while in tests).

I had also defined the setters to use write_attribute(:date_worked, 'SOMEVAL') and while that works within the application, for tests, I get errors like

ActiveModel::MissingAttributeError: can't write unknown attribute hours_worked'
app/models/time_bank.rb:110:in `hours_worked='

An example of a test would be as follows:

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

Both assertions always fail, since they get today's date and 0.0 (the "defaults" as specified in the getters). If I set the attributes on the line immediately before the tests, it still has no effect.

Im not sure what Im doing wrong. Id like to write tests for these 2 virtual attributes, but any setting of their values seems to have no effect. Im not sure why it doesnt work within tests, but works fine within the application. The same code works as expected within the application controllers. Can anyone help me understand why?


回答1:


The problem lies within the setter methods. Instead of assigning something to self.attributes["virtual_attribute"], an instance variable is needed to be set and returned, like so:

def virtual_attribute=(virtual_attr_value)
  @virtual_attribute = virtual_attr_value
end

So for my example, I needed:

def hours_worked=(hours_worked_val)
  @hours_worked = hours_worked_val
end

Both the application, and my getter/setter tests in minitest, behave as expected now.



来源:https://stackoverflow.com/questions/31999460/rails-4-minitest-testing-virtual-attributes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!