Rspec测试延迟工作
我的应用程序中有一些复杂的、长期运行的延迟作业流程。我使用Rspec来测试流程中使用的各个方法和类,但我也希望使用不同的测试数据执行许多端到端的后台工作 我在延迟工作维基上找不到关于这个的任何东西,所以这个问题看起来很有趣,但我真的不明白这里发生了什么。 我可以使用工厂轻松设置测试数据,然后调用启动后台处理的类。我预计测试需要很长时间才能完成 编辑的背景代码Rspec测试延迟工作,rspec,delayed-job,Rspec,Delayed Job,我的应用程序中有一些复杂的、长期运行的延迟作业流程。我使用Rspec来测试流程中使用的各个方法和类,但我也希望使用不同的测试数据执行许多端到端的后台工作 我在延迟工作维基上找不到关于这个的任何东西,所以这个问题看起来很有趣,但我真的不明白这里发生了什么。 我可以使用工厂轻松设置测试数据,然后调用启动后台处理的类。我预计测试需要很长时间才能完成 编辑的背景代码 class Singleplex def perform(batch_id,user) batch = sta
class Singleplex
def perform(batch_id,user)
batch = start_batch(batch_id,user)
... do lots of stuff ...
end
handle_asynchronously :perform, queue: :singleplex, :run_at => Proc.new { 1.second.from_now }
规格/工厂/批次。rb
FactoryGirl.define do
factory :batch do
batch_type 'singleplex'
name 'valid panel'
status 'ready'
end
factory :batch_detail do
chrom 7
chrom_start 140435012
chrom_end 140435012
target_offset 150
padding 4
primer3_parameter_id 1
snp_mask 't'
status 'ready'
batch
end
end
然后像这样运行测试
describe Batch do
it 'runs Singleplex for a valid panel' do
batch = FactoryGirl.create(:batch)
user = User.find(1)
status = Singleplex.new.perform(batch.id,user)
expect(status.should == true)
end
end
我有两个问题要解决:
1) 如何告诉测试在验证结果之前等待延迟的_作业调用完成
2) 为了验证结果,我需要检查多个表中的值。在Rspec中实现这一点的最佳方法是什么
编辑
我应该加上我得到了一个延迟的任务对象,所以状态检查当然失败了。这些工作通常至少需要10分钟
1) Batch runs Singleplex for a valid panel
Failure/Error: expect(status.should == true)
expected: true
got: #<Delayed::Backend::ActiveRecord::Job id: nil, priority: 0, attempts: 0, handler: "--- !ruby/object:Delayed::PerformableMethod\nobject:...", last_error: nil, run_at: nil, locked_at: nil, failed_at: nil, locked_by: nil, queue: nil, created_at: nil, updated_at: nil> (using ==)
1)批处理为有效面板运行Singleplex
失败/错误:预期(status.should==true)
预期:正确
got:#(使用==)
有几种方法可以做到这一点。所有这些都要求您在代码中执行作业
方法1:对作业进行排队,然后通知DelayedJob::Worker
完成作业的测试
describe Batch do
it 'runs Singleplex for a valid panel' do
batch = FactoryGirl.create(:batch)
user = User.find(1)
Singleplex.new.perform(batch.id,user)
expect(Delayed::Worker.new.work_off).to eq [1, 0] # Returns [successes, failures]
# Add expectations which check multiple tables to make sure the work is done
end
end
方法2:在禁用排队的情况下运行相关作业并检查所需结果的测试。您可以通过调用测试配置中的某个地方或之前的块中的延迟::Worker.delay_jobs=false来延迟排队
before(:each) do
Delayed::Worker.delay_jobs = false
end
describe Batch do
it 'runs Singleplex for a valid panel' do
batch = FactoryGirl.create(:batch)
user = User.find(1)
Singleplex.new.perform(batch.id,user)
# expectations which check that the work is done
end
end
然而,这种方法已经为大家所知
方法3:编写一个观察者,观察创建并运行的任何新作业。这样,您就不必在测试中手动声明“work_off”。Artsy有一个
在其他地方进行测试也是一个好主意,以确保作业按预期排队
it "queues welcome when a user is created" do
expect(Delayed::Job.count).to eq 0
# Create user step
expect(Delayed::Job.count).to eq 1 # You should really be looking for the count of a specific job.
end
如果要围绕单个测试或一组测试运行延迟作业,可以将其添加到spec_helper.rb中
config.around(:each, :run_delayed_jobs) do |example|
Delayed::Worker.delay_jobs = false
example.run
Delayed::Worker.delay_jobs = true
end
并称之为:
it 'runs the job', :run_delayed_jobs do
# delayed job magic
end
顺便说一句,看起来您混合了RSpec的should
和expect
语法expect(status.should==true)
应该是status.should==true
或expect(status)。to==true
感谢@faraz,对于方法3,您在哪里添加了对delayed\u job\u observer.rb的引用,它是否在spec\u helper.rb
中?如果您使用的是较新的组织格式,请使用rails\u helper.rb
,否则spec\u helper.rb
会起作用。在第一种方法中,不应该立即执行作业吗,它不会对其进行排队吗?@jshah不会立即执行该作业,因为在测试期间没有后台工作程序运行来使用该作业,除非出于某种疯狂的原因,您决定运行后台工作程序是个好主意。