Rails - How to stub a certain response time for a

2019-09-10 14:35发布

问题:

I want to test a feature that in my app sends the usera custom message when a Rails UJS/ajax times-out.

The code to timeout the Rails UJS request is itself on the app:

$.rails.ajax = function(options) {
      if (!options.timeout) {
        options.timeout = 10000;
      }    
      return $.ajax(options);
    };

When observing on chrome dev tools what happened when it timed out on my local dev mode, I notice the code status is strangely 200 but as it "times out", my message is indeed displayed to the user.

on('ajax:error',function(event,xhr, status, error){
        // display message in modal for users
              if(status == "timeout") {
                console.log( ' ajax request timed out');
                var msg;
                msg = Messenger().post({
                  hideAfter:  8,
                  message:    "Too long, the app timed out"
                });
              } 
            }             
          });

Below is my current test (using puffing bill gem). I managed to stub the http response for my ajax request but I don't know how to tell rspec to "wait" and timeout like take 11 seconds and still not send any response to the xhr call:) (xhr max timeout is set to 10 000 milliseconds above so 10 sec<11sec, it should time out inside the rspec test)

it " displays correct modal message appears  correctly when xhr call timeout" do
  visit deal_page_path(deal)    
  proxy.stub("http://127.0.0.1:59533/deals/dealname/ajaxrequest").and_return(:code => 200)
  first('a.button').click 
  wait_for_ajax
  within('ul.messenger') do           
    expect(page).to have_content('Too long, the app timed out')
  end
end

回答1:

If you really want it to just wait for the timeout I believe you can use the Proc version of and_return and sleep for as long as you want the request to take

proxy.stub("http://127.0.0.1:59533/deals/dealname/ajaxrequest").and_return(
  Proc.new { |params, headers, body|
    sleep 11
    {code: 200}
  } )

also - rather than wait_for_ajax just pass the amount of time you expect the element to take to appear to the within call

within('ul.messenger', wait: 11) do ...