Kreychek
Kreychek

Reputation: 727

How to test Ruby on Rails methods that involve asynchronous/parallel operations?

I have a method that creates a record and waits for it to receive input in a loop that occurs until the record's contents satisfy a check.

In normal use, the record that the method creates is presented in a form on a page that displays it after it has been created. Submission of the form updates the record, causing the loop to exit and the method to process the record's newly inputted data.

How can I write a test for this? I am not concerned with exactly simulating user input and everything that entails; I just want to be able to modify the record - a task normally accomplished by a separate process (an update from a form submission).

Example code within a rails model:

def self.create_and_wait_on_record(msg)
  rec = create(question: msg)

  # At this point a web page detects this record and displays it in a form

  # Loop until some field on rec has received input (normally via form submission)
  until rec.filled_in?  
    sleep 1.second
    rec.reload
  end

  # Processing rec follows...
end

Upvotes: 0

Views: 1120

Answers (1)

mcfinnigan
mcfinnigan

Reputation: 11638

Split the test into two sections.

Test the process up to the point you would wait for input.

Then test the process from the point that input is provided. All you're skipping is the submission of form data - and to my mind you don't need to be testing that.

Edit: clarification on your question below.

I'd redefine self.create_and_wait_on_record(msg) to work as follows:

def self.create_and_wait_on_record(msg)
  rec = create(question: msg)

  wait_and_process(rec)     
end

I'd have one test that verifies that create_and_wait_on_record creates the record and calls wait_and_process:

it 'Creates the record and continues processing when capable' do 
  subject.should_receive(:wait_and_process).with(stub_rec)
  subject.create_and_wait_on_record(mock_msg)
end

and one that continues the process

it 'Processes a record once it has been created and has had the requisite data populated' do 
   subject.stub(:create).and_return(mock_created_record)
   subject.create_and_wait_on_record(mock_msg)
end

Then you just need to make sure that you have the inputs set up for the test cases so that #filled_in? won't permaloop.

Upvotes: 2

Related Questions