Как выполнить модульное тестирование модуля (задание Resque Scheduler) в rspec
У меня есть (упрощенный) модуль: (/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
Этот тест не проходит каждый раз. Я использовал путы внутри модуля CheckPulse, чтобы проверить его, и он имеет ожидаемое поведение внутри модуля, но когда он возвращается из модуля, машина не изменилась.
Я попытался смешать модуль в фиктивный класс, но это тоже не сработало. Я также попытался запустить консоль rails в тестовой среде, чтобы проверить, не является ли это проблемой среды, но модуль там тоже работал нормально.
Я провел целый день на этом, пожалуйста, помогите!
1 ответ
Прежде всего, попробуйте следовать соглашениям ruby & rails. Если вы называете модуль 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)
- избегать круглых скобок в методах без аргументов