0

我有一个(简化的)模块:(/app/jobs/checkpulse.rb)

module CheckPulse
  @queue = :heartbeat
  def self.perform()
    Machine.all.each do |machine|
      machine.update_columns(active_alarm: true) #do not want to touch updated_at
    end
  end
end

我可以在 rails 控制台中使用它,它会按预期更改所有机器。

我正在尝试编写一个规范来测试它:(/spec/jobs/checkpulse_spec.rb)

require "spec_helper"
require_relative '../../app/jobs/checkpulse'

describe "CheckPulse" do

  let(:user) { FactoryGirl.create(:user) }
  let!(:machine) { FactoryGirl.create(:machine, user: user, heartbeat_timeout: 5) }

  it "should change the machine to alarm mode" do
    CheckPulse.perform
    expect(machine.active_alarm).to be_true
  end
end

这个测试每次都失败。我在 CheckPul​​se 模块中使用了 puts 来检查它,它在模块内部具有预期的行为,但是当它从模块返回时,机器没有改变。

我曾尝试将模块混合到一个虚拟类中,但这也不起作用。我还尝试在测试环境中运行 rails 控制台,看看是否是环境问题,但该模块在那里也可以正常工作。

我花了一整天的时间,请帮忙!

4

1 回答 1

1

首先,尝试遵循 ruby​​ 和 rails 约定。如果你调用模块CheckPulse,它的文件名应该是check_pulse.rb. 它将帮助您避免require_relative。其次,在规范和模块中,您与不同的 ruby​​ 对象进行交互,这些对象都写入数据库中的同一行。如果您更新一个对象,另一个对象将不会同步更新。您需要通过调用machine.reloadspec 手动重新加载它。

还有一些提示您的代码:

  • 从不使用all.each. 如果您的数据库中有 2k+ 条记录,它将卡住。对于迭代所有数据库记录使用find_each
  • update_all您可以使用->更新所有记录,而不是加载每条记录并更新它Machine.update_all(:column_1 => value_1, :column_2 => value_3)
  • 避免在没有参数的方法中使用圆括号
于 2014-04-23T23:45:32.730 回答