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
end
If 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
end
But 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)
end
Write the test:
describe ApplicationController, :type => :feature do
it "my test" do
visit some_path
expect(page).to have_content('Hello World')
end
end
And that’s it. Happy testing.
SHARE THIS PAGE!