标签: rails-activejob

如何使用rspec测试ActionMailer deliver_later

尝试使用delayed_job_active_record升级到Rails 4.2.我没有为测试环境设置delayed_job后端,因为工作会立即执行.

我正在尝试使用Rspec测试新的'deliver_later'方法,但我不确定如何.

旧控制器代码:

ServiceMailer.delay.new_user(@user)
Run Code Online (Sandbox Code Playgroud)

新控制器代码:

ServiceMailer.new_user(@user).deliver_later
Run Code Online (Sandbox Code Playgroud)

我用它来测试它是这样的:

expect(ServiceMailer).to receive(:new_user).with(@user).and_return(double("mailer", :deliver => true))
Run Code Online (Sandbox Code Playgroud)

现在我使用它会出错.(Double"mailer"收到意外消息:deliver_later with(no args))

只是

expect(ServiceMailer).to receive(:new_user)
Run Code Online (Sandbox Code Playgroud)

nil的'undefined方法`deliver_later'也失败了:NilClass'

我已经尝试了一些示例,允许您查看作业是否在ActiveJob中使用test_helper排队,但我还没有设法测试正确的作业是否排队.

expect(enqueued_jobs.size).to eq(1)
Run Code Online (Sandbox Code Playgroud)

如果包含test_helper,则会通过,但它不允许我检查它是否是正在发送的正确电子邮件.

我想做的是:

  • 测试正确的电子邮件是否已排队(或在测试环境中立即执行)
  • 使用正确的参数(@user)

有任何想法吗??谢谢

rspec ruby-on-rails actionmailer delayed-job rails-activejob

63
推荐指数
7
解决办法
2万
查看次数

如何在Active Job(Rails 4.2)中安排定期作业?

在Rails中找到了这个 Schedule一次性工作, 但这只显示了如何一次性安排.我有兴趣安排一份经常性的工作.

Delayed_job有这个

self.delay(:run_at => 1.minute.from_now)
Run Code Online (Sandbox Code Playgroud)

我如何在Rails 4.2/Active Job中做类似的事情?

ruby-on-rails ruby-on-rails-4 rails-activejob

37
推荐指数
3
解决办法
2万
查看次数

如何使用Rspec检查ActiveJob中排队的内容

我正在使用Rails API应用程序中的reset_password方法.当该端点被命中时,ActiveJob将排队,该命令将触发对Mandrill(我们的交易电子邮件客户端)的请求.我正在尝试编写测试以确保在控制器端点被命中时ActiveJob正确排队.

def reset_password
  @user = User.find_by(email: params[:user][:email])
  @user.send_reset_password_instructions
end
Run Code Online (Sandbox Code Playgroud)

send_reset_password_instructions在创建ActiveJob之前创建了一些url等,其代码如下:

class SendEmailJob < ActiveJob::Base
  queue_as :default

  def perform(message)
    mandrill = Mandrill::API.new
    mandrill.messages.send_template "reset-password", [], message
  rescue Mandrill::Error => e
    puts "A mandrill error occurred: #{e.class} - #{e.message}"
    raise
  end
end
Run Code Online (Sandbox Code Playgroud)

目前我们没有为ActiveJob使用任何适配器,所以我只想检查Rspec ActiveJob是否排队.

目前我的测试看起来像这样(我正在使用工厂女孩来创建用户):

require 'active_job/test_helper'

describe '#reset_password' do
  let(:user) { create :user }

  it 'should create an ActiveJob to send the reset password email' do
    expect(enqueued_jobs.size).to eq 0
    post :reset_password, user: { email: user.email }
    expect(enqueued_jobs.size).to eq 1
  end …
Run Code Online (Sandbox Code Playgroud)

ruby rspec ruby-on-rails rails-activejob

34
推荐指数
7
解决办法
3万
查看次数

Sidekiq Rails 4.2使用活动作业还是工作者?有什么不同

这是我第一次异步处理作业我在我的应用程序中实现Sidekiq进行后台处理.我会将它用于提醒电子邮件和应用内通知.我很困惑我是否应该使用Active Job创建一个发送电子邮件的工作或者Sidekiq Worker来发送电子邮件.他们似乎做同样的事情,Rails 4.2 Active Job似乎很新......它是否取代了对Sidekiq工作者的需求?

以下是使用Active Job作业和Sidekiq Worker发送邮件代码的相同内容.我正在使用Whenever gem进行调度.

my_mailers.rb

class MyMailers < ActionMailer::Base

  def some_mailer(r.user_id)
    @user = User.find(r.user_id)
    mailer_name = "ROUNDUP"
    @email = @user.email
    @subject ="subject text"
    mail(to: @email, 
      subject: @subject,  
      template_path: '/notifer_mailers', 
      template_name: 'hourly_roundup.html',
      )
  end
end
Run Code Online (Sandbox Code Playgroud)

使用Sidekiq"Worker"
some_worker.rb

class SomeWorker
  include Sidekiq::Worker

  def perform()
    @user = User.all
    @reminders = @user.reminders.select(:user_id).uniq.newmade
    @reminders.each do |r|
      MyMailers.some_mailer(r.user_id).deliver_later
    end
  end

end
Run Code Online (Sandbox Code Playgroud)

使用活动作业"作业"
some_job.rb

class SomeJob < ActiveJob::Base
  queue_as :mailer

  def perform()
    @user = User.all
    @reminders = @user.reminders.select(:user_id).uniq.newmade
    @reminders.each do |r| …
Run Code Online (Sandbox Code Playgroud)

asynchronous ruby-on-rails whenever sidekiq rails-activejob

30
推荐指数
3
解决办法
1万
查看次数

使用与Sidekiq一起使用的ActiveJob禁用自动重试

有没有办法禁用ActiveJob和Sidekiq的自动重试?

我知道只有Sidekiq,我们只需要放

sidekiq_options :retry => false
Run Code Online (Sandbox Code Playgroud)

如上所述:https://github.com/mperham/sidekiq/wiki/Error-Handling#configuration

但它似乎不适用于ActiveJob和Sidekiq.

我也知道这里提出的重新启用重试的解决方案:https://stackoverflow.com/a/28216822/2431728

但这不是我需要的行为.

ruby-on-rails sidekiq rails-activejob

19
推荐指数
4
解决办法
1万
查看次数

如何使用ActiveJob设置Sidekiq的重试次数?

从Rails API,我发现ActiveJob可以retry_job间隔:

my_job_instance.enqueue
my_job_instance.enqueue wait: 5.minutes
my_job_instance.enqueue queue: :important
my_job_instance.enqueue wait_until: Date.tomorrow.midnight
Run Code Online (Sandbox Code Playgroud)

http://api.rubyonrails.org/classes/ActiveJob/Enqueuing.html

但是如果我想设置重试计数,比如Sidekiq:

include Sidekiq::Worker
sidekiq_options :retry => 5
Run Code Online (Sandbox Code Playgroud)

https://github.com/mperham/sidekiq/wiki/Error-Handling

该示例代码怎么办?

class SiteScrapperJob < ActiveJob::Base
  rescue_from(ErrorLoadingSite) do
    retry_job queue: :low_priority
  end

  def perform(*args)
    # raise ErrorLoadingSite if cannot scrape
  end
end
Run Code Online (Sandbox Code Playgroud)

现在我把它添加到我的工作班:

Sidekiq.default_worker_options = { retry: 5 }
Run Code Online (Sandbox Code Playgroud)

但似乎不是很好.

sidekiq rails-activejob

19
推荐指数
4
解决办法
9852
查看次数

Action Job/Mailer的'deliver_now`和`deliver_later`之间的区别

ActionJob在Rails中连接的常见模式是使用一个perform()方法设置一个Job,该方法通过perform_now或者异步调用perform_later

在邮件程序的特殊情况下,可以直接打电话deliver_nowdeliver_later因为ActionJob是很好的集成ActionMailer.

轨道文档有以下评论-

# If you want to send the email now use #deliver_now
UserMailer.welcome(@user).deliver_now

# If you want to send the email through Active Job use #deliver_later
UserMailer.welcome(@user).deliver_later
Run Code Online (Sandbox Code Playgroud)

措辞使得它看起来像deliver_now不会使用ActiveJob发送邮件.那是正确的,如果有啥之间真正的差异deliver_nowdeliver_later?一个不是异步的吗?

同样,同样的差异适用于perform_nowperform_later

谢谢!

jobs ruby-on-rails rails-activejob

18
推荐指数
2
解决办法
2万
查看次数

在rspec中使用ActiveJob执行挂起作业

我有这个代码用Rspec测试ActiveJob和ActionMailer我不知道如何真正执行所有排队的工作

describe 'whatever' do
  include ActiveJob::TestHelper

  after do
    clear_enqueued_jobs
  end  

  it 'should email' do
    expect(enqueued_jobs.size).to eq(1)
  end
end
Run Code Online (Sandbox Code Playgroud)

rspec ruby-on-rails actionmailer rails-activejob

17
推荐指数
2
解决办法
8815
查看次数

Rails 4.2:使用deliver_later和无表格模型

我正在尝试使用Rails 4.2的deliver_later方法设置联系表单.但是,我只能让deliver_now工作,因为deliver_later正在尝试序列化我的对象并且每次都失败.

这是我的设置:

messages_controller.rb

class MessagesController < ApplicationController
  def new
    @message = Message.new
  end

  def create
    @message = Message.new(params[:message])
    if @message.valid?
      ContactMailer.contact_form(@message).deliver_later
      redirect_to root_path, notice: "Message sent! Thank you for contacting us."
    else
      render :new
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

contact_mailer.rb

class ContactMailer < ApplicationMailer
  default :to => Rails.application.secrets['email']

  def contact_form(msg)
    @message = msg
    mail(:subject => msg.subject, from: msg.email)
  end
end
Run Code Online (Sandbox Code Playgroud)

message.rb

class Message
    include ActiveModel::Model
    include ActiveModel::Conversion

    ## Not sure if this is needed ##
    include ActiveModel::Serialization

    extend ActiveModel::Naming

    attr_accessor :name, …
Run Code Online (Sandbox Code Playgroud)

ruby-on-rails rails-activejob

15
推荐指数
2
解决办法
4699
查看次数

SerializationError Rails ActiveJob时间和日期

有人知道一种干净的方法来避免ActiveJob::SerializationError在尝试序列化DateTime对象时发生这种情况吗?

我到目前为止的两个解决方案是:

  • dump在加载参数时调用Marshal/JSON/YAML 然后load返回到Job(这很糟糕,因为我需要修补邮件程序作业)
  • 猴子补丁DateTime像这样:

/lib/core_ext/time.rb

class Time

  include GlobalID::Identification

  def id
    self.to_i
  end

  def self.find(id)
    self.at(id.to_i)
  end
end
Run Code Online (Sandbox Code Playgroud)

/lib/core_ext/date.rb

class Date

  include GlobalID::Identification

  def id
    self.to_time.id
  end

  def self.find(id)
    Time.find(id).to_date
  end
end
Run Code Online (Sandbox Code Playgroud)

哪个也很糟糕.谁有更好的解决方案?

ruby ruby-on-rails ruby-on-rails-4 rails-activejob

14
推荐指数
1
解决办法
2415
查看次数