【问题标题】:Testing Cronjobs in Rails在 Rails 中测试 Cronjobs
【发布时间】:2018-09-25 16:12:04
【问题描述】:

我有一个 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

【问题讨论】:

    标签: ruby-on-rails rspec cron


    【解决方案1】:

    我找到的解决方法是单独测试一个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
    

    【讨论】:

      猜你喜欢
      • 2011-06-23
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多