我有一个在Thin上运行的Rails服务器和一个异步控制器操作。我想用RSpec测试它,但是我收到一个错误:
Failure/Error: get :access_token
ArgumentError:
uncaught throw :async
这是一个示例代码:
class SampleController < ApplicationController
def sample
EM.defer do
render json: { response: 'Hello World' }
request.env['async.callback'].call response
end
throw :async
end
end
require 'spec_helper'
describe SampleController, :type => :controller do
it "hello world" do
get :sample
expect(JSON.parse(response.body)[response]).to eq('Hello World')
end
end
我收到此错误的原因是:async只能由Thin服务器处理。 vanilla Rails控制器中没有可用的瘦服务器。
所以试过Capybara:
describe "GET /sample", type: feature do
it "hello world" do
visit sample_path
expect(JSON.parse(page.body)['response']).to eq('Hello World')
end
end
# In spec_helper.rb
Capybara.server do |app, port|
require 'rack/handler/thin'
Rack::Handler::Thin.run(app, :Port => port)
end
但我仍然得到同样的错误。我相信这是因为Thin需要以线程模式启动;而且水豚没有以这种方式启动它。
使用throw:async测试控制器操作的正确方法是什么?
当我使用常规浏览器访问它时,该操作会起作用。
答案 0 :(得分:3)
为了测试使用Thin实现的异步Ruby on Rails操作,您需要使用Thin运行测试。否则它会失败,或者变脆 - 以防你尝试嘲笑。
所以让我们使用Capybara设置它:
在Gemfile中:
gem 'thin'
gem 'capybara'
gem 'selenium-webdriver'
在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
这将Capybara驱动程序设置为selenium,一个真正的浏览器。第二部分将Capybara服务器配置为Thin。
测试应该写成:
describe SampleController, :type => :feature do
it "my test" do
visit sample_path
expect(page).to have_content('Hello World')
end
end
这将使测试通过。
答案 1 :(得分:-1)
在RSpec控制器测试中,尝试替换
get :sample
与
expect { get :sample }.to throw_symbol(:async)
应该抓住它并防止规范失败。它还测试控制器是否异步!