myl*_*scc 34 ruby rspec ruby-on-rails rails-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
end
Run Code Online (Sandbox Code Playgroud)
一切都在现实中,我只需要创建测试!
我正在使用ruby 2.1.2和rails 4.1.6.
我无法在网上任何地方看到任何文档或帮助如何测试,所以任何帮助将不胜感激!
Jos*_*ith 46
接受的答案对我来说不再适用,所以我在评论中尝试了Michael H.的建议.
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)
dre*_*-hh 35
您真的不需要测试ActiveJob功能.只需测试一下代码是否正确调用它即可
expect(MyJob).to receive(:perform_later).once
post :reset_password, user: { email: user.email }
Run Code Online (Sandbox Code Playgroud)
ActiveJob的创建者使用相同的技术进行单元测试.请参阅GridJob Testobject
他们在测试中创建了一个testmock GridJob并覆盖了perform方法,因此它只将作业添加到自定义数组中,它们调用JobBuffer.最后他们测试缓冲区是否有作业入队
但是,如果没有什么不能阻止你做一个完整的集成测试.ActiveJob test_helper.rb应该与minitest一起使用而不是与rspec一起使用.所以你必须重建它的功能.你可以打电话
expect(ActiveJob::Base.queue_adapter.enqueued_jobs).to eq 1
Run Code Online (Sandbox Code Playgroud)
不需要任何东西
更新1:
在评论中注意到.
ActiveJob::Base.queue_adapter.enqueued_jobs仅通过将queue_adapter设置为测试模式来工作.
# either within config/environment/test.rb
config.active_job.queue_adapter = :test
# or within a test setup
ActiveJob::Base.queue_adapter = :test
Run Code Online (Sandbox Code Playgroud)
tir*_*adc 16
Rspec 3.4现在已经熟化了have_enqueued_job,这使得测试更加容易:
it "enqueues a YourJob" do
expect {
get :your_action, {}
}.to have_enqueued_job(YourJob)
end
Run Code Online (Sandbox Code Playgroud)
它有其他细节have_enqueued_job可以让你检查参数和它应该排队的次数.
class MyJob < ActiveJob::Base
queue_as :urgent
rescue_from(NoResultsError) do
retry_job wait: 5.minutes, queue: :default
end
def perform(*args)
MyService.call(*args)
end
end
require 'rails_helper'
RSpec.describe MyJob, type: :job do
include ActiveJob::TestHelper
subject(:job) { described_class.perform_later(123) }
it 'queues the job' do
expect { job }
.to change(ActiveJob::Base.queue_adapter.enqueued_jobs, :size).by(1)
end
it 'is in urgent queue' do
expect(MyJob.new.queue_name).to eq('urgent')
end
it 'executes perform' do
expect(MyService).to receive(:call).with(123)
perform_enqueued_jobs { job }
end
it 'handles no results error' do
allow(MyService).to receive(:call).and_raise(NoResultsError)
perform_enqueued_jobs do
expect_any_instance_of(MyJob)
.to receive(:retry_job).with(wait: 10.minutes, queue: :default)
job
end
end
after do
clear_enqueued_jobs
clear_performed_jobs
end
end
Run Code Online (Sandbox Code Playgroud)
有一个新的rspec扩展,让您的生活更轻松.
require 'rails_helper'
RSpec.describe MyController do
let(:user) { FactoryGirl.create(:user) }
let(:params) { { user_id: user.id } }
subject(:make_request) { described_class.make_request(params) }
it { expect { make_request }.to enqueue_a(RequestMaker).with(global_id(user)) }
end
Run Code Online (Sandbox Code Playgroud)
在我看来,确保执行请求时作业已排队很重要。您可以使用以下解决方案来做到这一点:
expect{ post your_api_here, params: params, headers: headers }
.to have_enqueued_job(YourJob)
.with(args)
Run Code Online (Sandbox Code Playgroud)
expect(YourJob).to receive(:perform_later).once.with(args)
post your_api_here, params: params, headers: headers
Run Code Online (Sandbox Code Playgroud)
小智 5
我遇到了一些问题,也许是因为我没有包含 ActiveJob::TestHelper,但这对我有用...
首先确保您将队列适配器设置:test为如上答案所示。
出于某种原因clear_enqueued_jobs,after块中的工作对我不起作用,但来源显示我们可以执行以下操作:enqueued_jobs.clear
require 'rails_helper'
include RSpec::Rails::Matchers
RSpec.describe "my_rake_task", type: :rake do
after do
ActiveJob::Base.queue_adapter.enqueued_jobs.clear
end
context "when #all task is run" do
it "enqueues jobs which have been enabled" do
enabled_count = get_enabled_count
subject.execute
expect(ActiveJob::Base.queue_adapter.enqueued_jobs.size).to eq(enabled_count)
end
it "doesn't enqueues jobs which have been disabled" do
enabled_count = get_enabled_count
subject.execute
expect(ActiveJob::Base.queue_adapter.enqueued_jobs.size).to eq(enabled_count)
end
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27836 次 |
| 最近记录: |