2014-10-26 15 views
21

Tôi có một số quy trình phức tạp, trì hoãn lâu dài trong ứng dụng của mình. Tôi đang sử dụng Rspec để kiểm tra các phương thức và các lớp riêng lẻ được sử dụng trong các quy trình, nhưng tôi cũng muốn thực hiện nhiều công việc nền cuối cùng, với các dữ liệu thử nghiệm khác nhau.Kiểm tra Rspec delay_job

Tôi không thể tìm thấy bất kỳ nội dung nào trên wiki về sự cố này và câu hỏi SO này có vẻ thú vị nhưng tôi thực sự không hiểu điều gì đang xảy ra ở đây. What's the best way to test delayed_job chains with rSpec?

Tôi có thể dễ dàng thiết lập dữ liệu thử nghiệm với một nhà máy, sau đó gọi lớp bắt đầu xử lý nền. Tôi hy vọng các thử nghiệm sẽ mất nhiều thời gian để hoàn thành.

sửa mã nền

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 } 

đặc tả/nhà máy/batches.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 

Sau đó chạy thử nghiệm như thế này

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 

Tôi có hai vấn đề cần giải quyết:

1) Làm cách nào để yêu cầu thử nghiệm đợi cho đến khi cuộc gọi delay_job hoàn thành trước khi xác thực kết quả?

2) Để xác thực kết quả, tôi sẽ cần kiểm tra các giá trị trong nhiều bảng. Cách tốt nhất để làm điều này trong Rspec là gì?

EDIT

tôi nên thêm tôi nhận được một đối tượng delayed_job, nên dĩ nhiên việc kiểm tra tình trạng thất bại. Công việc thường mất ít nhất 10 phút.

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 ==) 
+2

Bằng cách này, có vẻ như bạn đang trộn should' và 'cú pháp expect' của RSpec '. 'expect (status.should == true)' phải là 'status.should == true' hoặc' expect (status) .to == true' – fny

Trả lời

31

Có một số cách để thực hiện việc này. Tất cả đều yêu cầu bạn thực hiện công việc trong mã của bạn.

Phương pháp 1: Thử nghiệm xếp hàng đợi công việc và sau đó yêu cầu DelayedJob::Worker hoàn thành.

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 

Phương pháp 2: Thử nghiệm chạy công việc được đề cập với hàng đợi bị vô hiệu hóa và kiểm tra kết quả mong muốn. Bạn có thể trì hoãn việc xếp hàng bằng cách gọi Delayed::Worker.delay_jobs = false ở đâu đó trong cấu hình thử nghiệm của bạn hoặc trong khối before.

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 

Phương pháp này, tuy nhiên, được biết là cause issues with callbacks.

Phương pháp 3: Viết người quan sát theo dõi mọi công việc mới được tạo và chạy chúng. Bằng cách này bạn sẽ không phải tự khai báo "work_off" trong các bài kiểm tra của mình. Artsy có gist for this.

Nó cũng là một ý tưởng tốt để có các bài kiểm tra ở những nơi khác mà đảm bảo công việc được xếp hàng như mong đợi

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 
+0

Thanks @faraz, cho phương thức 3, bạn đã thêm tham chiếu vào đâu 'delay_job_observer.rb', là nó trong' spec_helper.rb'? – Dean

+0

Sử dụng 'rails_helper.rb' nếu bạn đang sử dụng định dạng tổ chức mới hơn, nếu không' spec_helper.rb' sẽ hoạt động. – fny

+0

trong phương pháp đầu tiên của bạn, không nên thực hiện công việc ngay lập tức, nó sẽ không xếp hàng đúng không? – jshah

5

Nếu bạn muốn chạy chậm công việc xung quanh thử nghiệm đơn lẻ hoặc một tập hợp các bài kiểm tra, bạn có thể thêm video này vào bạn spec_helper.RB

config.around(:each, :run_delayed_jobs) do |example| 
    Delayed::Worker.delay_jobs = false 

    example.run 

    Delayed::Worker.delay_jobs = true 
end 

Và gọi nó với:

it 'runs the job', :run_delayed_jobs do 
    # delayed job magic 
end 
Các vấn đề liên quan