如何在rspec中对模块(resque调度程序作业)进行单元测试

时间:2014-04-23 21:03:04

标签: ruby-on-rails unit-testing rspec resque resque-scheduler

我有一个(简化的)模块:(/ 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模块中使用了put来检查它,它在模块内部有预期的行为,但是当它从模块返回时,机器没有改变。

我尝试了mixing the module into a dummy class,但这也没有用。我也尝试在测试环境中运行rails console以查看它是否是一个环境问题,但该模块在那里工作正常。

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

1 个答案:

答案 0 :(得分:1)

首先,尝试遵循ruby&铁路惯例。如果您调用模块CheckPulse,则其文件名应为check_pulse.rb。它可以帮助您避免require_relative。其次,在规范和模块中,您与不同的ruby对象进行交互,这些对象都写入数据库中的同一行。如果更新一个对象,则不会同步更新另一个对象。您需要通过调用规范中的machine.reload手动重新加载它。

您的代码提示也很少:

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