In the previous article you learnt how to write a Rails action that can handle concurrent users, an asynchronous action. Today you are going to learn how to write an RSpec test for it.
This is the controller we want to write a test for:
class ApplicationController < ActionController::Base
  def sample
    EM.defer do
      render json: { response: 'Hello World' }
      request.env['async.callback'].call response
    end
    throw :async
  end
endIf this were not an asynchronous action, we would simply write a test like this:
require 'spec_helper'
describe ApplicationController, :type => :controller do
  it "hello world" do
    get :sample
    expect(JSON.parse(response.body)['response']).to eq('Hello World')
  end
endBut this won’t work because throw :async will kill the action right away. throw :async will make the interpreter go to this line of code defined in the Thin gem. The problem is that Thin is not loaded at all when running a controller test.
In order to properly test an asynchronous action you need to run the test using a real Thin server. You can use Capybara to do that.
Gemfile
gem 'thin'
gem 'capybara'
gem 'selenium-webdriver'In spec/rails_helper.rb:
require 'capybara/rails'
Capybara.default_driver = :selenium
Capybara.server do |app, port|
  require 'rack/handler/thin'
  Rack::Handler::Thin.run(app, :Port => port)
endWrite the test:
describe ApplicationController, :type => :feature do
  it "my test" do
    visit some_path
    expect(page).to have_content('Hello World')
  end
endAnd that’s it. Happy testing.
SHARE THIS PAGE!