Rails 4.2 更新方法仅在从 before(:all) 块调用时失败
Rails 4.2 update method fails only when called from before(:all) block
更新
我在 rspec 中使用 -b 选项运行以获得完整的回溯。在
中调用了 clear 方法
actionpack-4.2.0/lib/action_controller/test_case.rb which is shown directly below
def reset_template_assertion
RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
instance_variable_get("@_#{instance_variable}").clear
end
end
同一文件中有一个 setup_subscriptions 方法应该将这些变量设置为 {}。看起来这个方法没有被调用 before(:all) 块
def setup_subscriptions
RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
instance_variable_set("@_#{instance_variable}", Hash.new(0))
end
...
...
...
end
我不确定这是不是一个错误,或者我需要更新一些其他的 gem。
原始问题(更新回溯)
当我运行 bundle exec rspec
时出现以下错误
> 1) user api get / index with no parameters passed it returns the first 30 users
> Failure/Error: user_and_token = gen_valid_user_and_api_token("foobar")
> NoMethodError:
> undefined method `clear' for nil:NilClass
> # ... /gems/actionpack-4.2.0/lib/action_controller/test_case.rb:70:in `block in reset_template_assertion'
> # ... /gems/actionpack-4.2.0/lib/action_controller/test_case.rb:69:in `each'
> # ... /gems/actionpack-4.2.0/lib/action_controller/test_case.rb:69:in `reset_template_assertion'
> # ... /gems/actionpack-4.2.0/lib/action_dispatch/testing/integration.rb:341:in `block (2 levels) in <module:Runner>'
> # ./spec/support/utilities.rb:22:in `gen_valid_user_and_api_token'
> # ./spec/requests/api/v1/user_api_spec.rb:7:in `block (2 levels) in <top (required)>'
失败的方法调用是下面的 post
行
./spec/support/utilities.rb:第 22 行是
post '/api/v1/signup', { user: { name: attrs[:name], email: attrs[:email], password: password, password_confirmation: password }}
<小时>
./spec/support/utilities.rb中的完整方法:
def gen_valid_user_and_api_token(password)
attrs = FactoryGirl.attributes_for(:user)
post '/api/v1/signup', { user: { name: attrs[:name], email: attrs[:email], password: password, password_confirmation: password }}
raw_token = parse_json_body(response)['token']
access_token = Token.get_number_field(raw_token)
target_user = Token.get_id_field(raw_token)
user = User.find_by_id(target_user)
{ user: user, token: { api_access_token: "#{user.id}:#{access_token}" } } if user
end
当我从一个 before 块调用这个方法时,它似乎工作正常
before do
@user_and_token = gen_valid_user_and_api_token("foobar")
@user = @user_and_token[:user]
@user_token_hash = @user_and_token[:token]
当我从 before(:all) 块调用此函数时,出现上述错误。
before(:all) do
@initial_user_count = User.count
user_and_token = gen_valid_user_and_api_token("foobar")
@valid_user = user_and_token[:user]
@valid_token_hash = user_and_token[:token]
在从 rails 4.1.8 更新到 rails 4.2.0 之前一切正常。
下面是我的 Gemfile:
我从 4.1.8 到 4.2.0 所做的唯一更改是更改 rails gem、添加响应程序 gem 并更改 turbolinks gem 从 1.1.1 -> 2.3.0(修复了调用 redirect_to 时“错误数量”的问题,我仍在努力理解原因。
source 'https://rubygems.org'
ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0
# gem 'rails', '~>4.1.0'
gem 'rails', '~>4.2.0'
gem 'bootstrap-sass', '2.3.2.0'
gem 'bcrypt-ruby', '3.1.2'
gem 'faker', '1.1.2'
gem 'will_paginate', '3.0.4'
gem 'bootstrap-will_paginate', '0.0.9'
gem 'sprockets', '2.11.0'
gem 'pg', '0.15.1'
gem 'responders', '~> 2.0'
## added for google maps
gem 'jquery-turbolinks'
# gem 'gmaps4rails'
gem 'gmapsjs-rails'
##
gem 'rest_client'
gem "puma"
gem "gcm"
gem "geocoder"
gem "figaro"
# gem "pg_search"
group :development, :test do
#gem 'sqlite3', '1.3.8'
gem 'guard', '= 2.7.3'
gem 'rspec-rails', '~>2.14.0'
# The following optional lines are part of the advanced setup.
gem 'guard-rspec', '2.5.0'
gem 'spork-rails', '4.0.0'
gem 'guard-spork', '1.5.0'
gem 'childprocess', '0.3.6'
gem "teaspoon"
# gem "phantomjs-binaries"
# gem "phantomjs.rb"
end
group :test do
gem 'selenium-webdriver', '2.35.1'
gem 'capybara', '2.1.0'
gem 'factory_girl_rails', '4.2.0'
gem 'cucumber-rails', '1.3.0', :require => false
gem 'database_cleaner', github: 'bmabey/database_cleaner'
# Uncomment this line on OS X.
#gem 'growl', '1.0.3'
# Uncomment these lines on Linux.
gem 'libnotify', '0.8.0'
#Uncomment these lines on Windows.
#gem 'rb-notifu', '0.0.4'
#gem 'win32console', '1.3.2'
#gem 'wdm', '0.1.0'
end
gem 'sass-rails', '4.0.1'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.1'
gem 'jquery-rails', '3.0.4'
gem 'jquery-ui-rails', '4.2.1'
gem 'turbolinks', '~> 2.3.0'
# gem 'turbolinks', '1.1.1'
gem 'jbuilder', '1.0.2'
group :doc do
gem 'sdoc', '0.3.20', require: false
end
group :production do
gem 'unicorn'
#gem 'pg', '0.15.1'
gem 'rails_12factor', '0.0.2'
end
...只是清理一些我问过但从未得到回答的问题
正如 Peter Alfvin 在他的评论中提到的,这确实是一个错误,我认为将在下一个 rails 版本中修复。不管它的价值如何,我真的没有理由需要我在 before(:all) 块上的代码。我能够将它移到 before(:each) 块中,一切正常。
更新
我在 rspec 中使用 -b 选项运行以获得完整的回溯。在
中调用了 clear 方法actionpack-4.2.0/lib/action_controller/test_case.rb which is shown directly below
def reset_template_assertion
RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
instance_variable_get("@_#{instance_variable}").clear
end
end
同一文件中有一个 setup_subscriptions 方法应该将这些变量设置为 {}。看起来这个方法没有被调用 before(:all) 块
def setup_subscriptions
RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
instance_variable_set("@_#{instance_variable}", Hash.new(0))
end
...
...
...
end
我不确定这是不是一个错误,或者我需要更新一些其他的 gem。
原始问题(更新回溯)
当我运行 bundle exec rspec
时出现以下错误> 1) user api get / index with no parameters passed it returns the first 30 users
> Failure/Error: user_and_token = gen_valid_user_and_api_token("foobar")
> NoMethodError:
> undefined method `clear' for nil:NilClass
> # ... /gems/actionpack-4.2.0/lib/action_controller/test_case.rb:70:in `block in reset_template_assertion'
> # ... /gems/actionpack-4.2.0/lib/action_controller/test_case.rb:69:in `each'
> # ... /gems/actionpack-4.2.0/lib/action_controller/test_case.rb:69:in `reset_template_assertion'
> # ... /gems/actionpack-4.2.0/lib/action_dispatch/testing/integration.rb:341:in `block (2 levels) in <module:Runner>'
> # ./spec/support/utilities.rb:22:in `gen_valid_user_and_api_token'
> # ./spec/requests/api/v1/user_api_spec.rb:7:in `block (2 levels) in <top (required)>'
失败的方法调用是下面的 post
行
./spec/support/utilities.rb:第 22 行是
post '/api/v1/signup', { user: { name: attrs[:name], email: attrs[:email], password: password, password_confirmation: password }}
<小时>
./spec/support/utilities.rb中的完整方法:
def gen_valid_user_and_api_token(password)
attrs = FactoryGirl.attributes_for(:user)
post '/api/v1/signup', { user: { name: attrs[:name], email: attrs[:email], password: password, password_confirmation: password }}
raw_token = parse_json_body(response)['token']
access_token = Token.get_number_field(raw_token)
target_user = Token.get_id_field(raw_token)
user = User.find_by_id(target_user)
{ user: user, token: { api_access_token: "#{user.id}:#{access_token}" } } if user
end
当我从一个 before 块调用这个方法时,它似乎工作正常
before do
@user_and_token = gen_valid_user_and_api_token("foobar")
@user = @user_and_token[:user]
@user_token_hash = @user_and_token[:token]
当我从 before(:all) 块调用此函数时,出现上述错误。
before(:all) do
@initial_user_count = User.count
user_and_token = gen_valid_user_and_api_token("foobar")
@valid_user = user_and_token[:user]
@valid_token_hash = user_and_token[:token]
在从 rails 4.1.8 更新到 rails 4.2.0 之前一切正常。
下面是我的 Gemfile:
我从 4.1.8 到 4.2.0 所做的唯一更改是更改 rails gem、添加响应程序 gem 并更改 turbolinks gem 从 1.1.1 -> 2.3.0(修复了调用 redirect_to 时“错误数量”的问题,我仍在努力理解原因。
source 'https://rubygems.org'
ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0
# gem 'rails', '~>4.1.0'
gem 'rails', '~>4.2.0'
gem 'bootstrap-sass', '2.3.2.0'
gem 'bcrypt-ruby', '3.1.2'
gem 'faker', '1.1.2'
gem 'will_paginate', '3.0.4'
gem 'bootstrap-will_paginate', '0.0.9'
gem 'sprockets', '2.11.0'
gem 'pg', '0.15.1'
gem 'responders', '~> 2.0'
## added for google maps
gem 'jquery-turbolinks'
# gem 'gmaps4rails'
gem 'gmapsjs-rails'
##
gem 'rest_client'
gem "puma"
gem "gcm"
gem "geocoder"
gem "figaro"
# gem "pg_search"
group :development, :test do
#gem 'sqlite3', '1.3.8'
gem 'guard', '= 2.7.3'
gem 'rspec-rails', '~>2.14.0'
# The following optional lines are part of the advanced setup.
gem 'guard-rspec', '2.5.0'
gem 'spork-rails', '4.0.0'
gem 'guard-spork', '1.5.0'
gem 'childprocess', '0.3.6'
gem "teaspoon"
# gem "phantomjs-binaries"
# gem "phantomjs.rb"
end
group :test do
gem 'selenium-webdriver', '2.35.1'
gem 'capybara', '2.1.0'
gem 'factory_girl_rails', '4.2.0'
gem 'cucumber-rails', '1.3.0', :require => false
gem 'database_cleaner', github: 'bmabey/database_cleaner'
# Uncomment this line on OS X.
#gem 'growl', '1.0.3'
# Uncomment these lines on Linux.
gem 'libnotify', '0.8.0'
#Uncomment these lines on Windows.
#gem 'rb-notifu', '0.0.4'
#gem 'win32console', '1.3.2'
#gem 'wdm', '0.1.0'
end
gem 'sass-rails', '4.0.1'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.1'
gem 'jquery-rails', '3.0.4'
gem 'jquery-ui-rails', '4.2.1'
gem 'turbolinks', '~> 2.3.0'
# gem 'turbolinks', '1.1.1'
gem 'jbuilder', '1.0.2'
group :doc do
gem 'sdoc', '0.3.20', require: false
end
group :production do
gem 'unicorn'
#gem 'pg', '0.15.1'
gem 'rails_12factor', '0.0.2'
end
...只是清理一些我问过但从未得到回答的问题
正如 Peter Alfvin 在他的评论中提到的,这确实是一个错误,我认为将在下一个 rails 版本中修复。不管它的价值如何,我真的没有理由需要我在 before(:all) 块上的代码。我能够将它移到 before(:each) 块中,一切正常。