Rails 4 Minitest Тестване на виртуални атрибути

Така че имам клас TimeBank и той се актуализира и получава два нови виртуални атрибута, които ще манипулират два други съществуващи атрибута (DB колони).

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 и 0.0 за hours_worked. Сетерите изглеждат неотзивчиви, сякаш не правят нищо (докато са в тестове).

Бях също дефинирал настройките да използват 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 („по подразбиране“, както е посочено в гетърите). Ако задам атрибутите на реда непосредствено преди тестовете, пак няма ефект.

Не съм сигурен какво правя погрешно. Искам да напиша тестове за тези 2 виртуални атрибута, но всяка настройка на техните стойности изглежда няма ефект. Не съм сигурен защо не работи в рамките на тестовете, но работи добре в приложението. Същият код работи както се очаква в контролерите на приложението. Може ли някой да ми помогне да разбера защо?


person Todd    schedule 13.08.2015    source източник


Отговори (1)


Проблемът е в методите на настройка. Вместо да се присвоява нещо на 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 се държат според очакванията сега.

person Todd    schedule 17.08.2015