在Rails中测试Cronjobs

时间:2018-09-24 11:39:26

标签: ruby-on-rails rspec cron

我有一个cronjob,可根据已达到的截止日期将用户从一张桌子转移到另一张桌子。

此cronjob可在Rails控制台中使用,但测试为红色。如果我从此cronjob测试功能,则测试为绿色。当我使用binding.pry进入cronjob时,它拥有所有必要的变量并正常工作。

有什么问题吗?

测试:

describe 'try various methods' do
    before(:each) do
      Obparticipant::Participant.all.delete_all
      @content = FactoryBot.create(:content, :with_department_ob, target_group: 'child', subject: 'Infos für Teilnehmer aus {ort}', message: '«{geschlecht} | Lieber | Liebe» {vorname}, du bist am {geburtsdatum} geboren.', notification_email: '{nachname}, {straße}, {plz}, {wohnland}, {bundesland}, {landesgruppe}')
      germany = ::Physical::Base::Country.GERMAN
      address = FactoryBot.create(:address, addressline_1: 'Sesamstraße', addressline_2: 'Kaufmannstraße', state: 'Bayern', city: 'München', zip: '80331', country_id: germany.id)
      person = FactoryBot.create(:person, firstname: 'Pablo', lastname: 'Domingo', dateofbirth: Date.new(2001,2,3), gender: 'm', address_id: address.id)
      @participant = FactoryBot.create(:participant, person_id: person.id)
      @participant.open_todos.by_task(:account_data).each{ |t| t.complete! } 
    end

it 'should move recipients with a start_date of today back to content_recipients' do
  person_two = FactoryBot.create(:person)
  participant_two = FactoryBot.create(:participant, person_id: person_two.id, program_season_id: @participant.program_season_id)
  participant_two.open_todos.by_task(:account_data).each{ |t| t.complete! }
  filter = '{"program_season":"' + @participant.program_season_id.to_s + '"}'
  @content.update_attributes(for_dynamic_groups: true, filter: filter, is_draft: false, delay_days: 5)
  FactoryBot.create(:delayed_content_recipient, content_id: @content.id, recipient_id: participant_two.id, start_date: Date.today)
  expect(@content.content_recipients.size).to eq(0)
  Cronjobs.check_recipients # or @content.insert_open_recipients
  expect(@content.delayed_content_recipients.size).to eq(1)
  expect(@content.content_recipients.map(&:recipient_id).last).to eq(participant_two.id) # this expectation fails, when a cronjob is tested, and passes, when a function is tested
end`

Cronjob:

def self.check_recipients
    contents = ::Content.published.current.by_for_dynamic_groups(true)
    contents.each do |content|
      content.insert_open_recipients
    end
  end

功能

def insert_open_recipients
    search = ::SimpleParticipantSearch.new(JSON.parse(self.filter))
    new_recipients = search.result.without_content(self.id)
    new_recipients.each do |nr|
      if self.delay_days.present?
        unless self.delayed_content_recipients.map(&:recipient_id).include?(nr.id)
          self.delayed_content_recipients.create(content_id: self.id, recipient_id: nr.id, start_date: Date.today + self.delay_days.days)
        end
      else
        self.participant_recipients << nr unless errors_with_participant?(nr)
      end
    end
    if self.delayed_content_recipients.any?
      self.delayed_content_recipients.each do |recipient|
        if new_recipients.map(&:id).include?(recipient.recipient_id)
          if recipient.start_date == Date.today
             self.delayed_content_recipients.delete(recipient)
              self.participant_recipients << Obparticipant::Participant.find_by(id: recipient.recipient_id) unless errors_with_participant?(Obparticipant::Participant.find_by(id: recipient.recipient_id))
          end
        else
          self.delayed_content_recipients.delete(recipient)
        end
      end
    end
  end

1 个答案:

答案 0 :(得分:0)

我找到的解决方案是分别测试Cronjob是否运行以及它调用的函数是否有效。

我在cronjobs控制器rspec中为此Cronjob编写了一个存根

it 'should call the correct method on the Cronjobs.check_recipients object' do
  Cronjobs.stub(:check_recipients)
  post :create, job: 'CheckRecipients'
  expect(Cronjobs).to have_received(:check_recipients)
  expect(response).to have_http_status(200)
end

并在上面提供的测试中测试了功能。

   it 'should move recipients with a start_date of today back to content_recipients' do
      person_two = FactoryBot.create(:person)
      participant_two = FactoryBot.create(:participant, person_id: person_two.id, program_season_id: @participant.program_season_id)
      participant_two.open_todos.by_task(:account_data).each{ |t| t.complete! }
      filter = '{"program_season":"' + @participant.program_season_id.to_s + '"}'
      @content.update_attributes(for_dynamic_groups: true, filter: filter, is_draft: false, delay_days: 5)
      FactoryBot.create(:delayed_content_recipient, content_id: @content.id, recipient_id: participant_two.id, start_date: Date.today)
      expect(@content.content_recipients.size).to eq(0)
      @content.insert_open_recipients
      expect(@content.delayed_content_recipients.size).to eq(1)
      expect(@content.content_recipients.map(&:recipient_id).last).to eq(participant_two.id)
    end