Ruby on rails RSpec,Capybara:将_重定向到不在创建/发布规范中工作
我设置了一个简单的控制器,其功能符合规格: stamps\u controller.rbRuby on rails RSpec,Capybara:将_重定向到不在创建/发布规范中工作,ruby-on-rails,selenium,rspec,capybara,Ruby On Rails,Selenium,Rspec,Capybara,我设置了一个简单的控制器,其功能符合规格: stamps\u controller.rb class StampsController < ApplicationController def new @stamp = Stamp.new end def create @stamp = Stamp.new(stamp_params) if @stamp.save redirect_to(stamp_url(@stamp.id), statu
class StampsController < ApplicationController
def new
@stamp = Stamp.new
end
def create
@stamp = Stamp.new(stamp_params)
if @stamp.save
redirect_to(stamp_url(@stamp.id), status: 201)
else
render 'new'
end
end
def show
@stamp = Stamp.find(params[:id])
end
private
def stamp_params
params.require(:stamp).permit(::percentage)
end
end
RSpec.describe 'stamp requests', type: :request do
describe 'stamp creation', js: true do
before do
FactoryBot.create_list(:domain, 2)
FactoryBot.create_list(:label, 2)
end
it 'allows users to create new stamps' do
visit new_stamp_path
expect(page).to have_content('Percentage')
find('#stamp_percentage').set('20')
click_button 'Create'
expect(current_path).to eq(stamp_path(Stamp.first.id))
end
end
end
根据:
Capybara会自动执行任何重定向,并提交与按钮关联的表单
但这不会在测试中发生,而是抛出一个错误:
预期:“/stamps/1”
得到:“/邮票”
结果很明显:它成功地创建了戳记,但未能重定向到新戳记。我还通过使用binding.pry
确认了这一点
为什么水豚不按照文档中描述的重定向?
旁注:
问题可能是提交表单后,
current\u path
需要一段时间才能更改。如果将sleep(x)
放在expect(current\u path)
之前,则代码可以工作
相反,您应该使用具有所谓“等待行为”的方法,例如具有当前路径
,具有当前路径
,断言当前路径
:
expect(page).to have_current_path(stamp_path(Stamp.first.id))
或
问题可能是提交表单后,
current\u path
需要一段时间才能更改。如果将sleep(x)
放在expect(current\u path)
之前,则代码可以工作
相反,您应该使用具有所谓“等待行为”的方法,例如具有当前路径
,具有当前路径
,断言当前路径
:
expect(page).to have_current_path(stamp_path(Stamp.first.id))
或
您的测试中有许多问题 首先,Capybara不应用于
请求
规范中,而应用于功能/系统测试。一旦您确定不再需要将Capybara包括在每个RSpec测试中,并应从您的配置中删除config.include Capybara::DSL
(当您需要capybara/rspec
时,它会将capybara包含在测试类型中,它应该包含在-)
其次,单击按钮
不保证等待它触发的任何操作完成。因此,在尝试访问该操作创建的任何数据库对象之前,您需要等待可视页面更改(从技术上讲,您根本不应该在特性规范中直接访问数据库,但如果您打算…)
第三,正如@chumakoff所指出的,您不应该对Capybara使用静态匹配器,而应该使用Capybara提供的匹配器
click_button 'Create'
expect(page).to have_text('Stamp created!') # Whatever message is shown after creation
expect(page).to have_path(stamp_path(Stamp.first.id))
最后,你应该查看你的test.log
,并使用save_和_open_屏幕截图查看你的控制器实际做了什么-实际上,在创建时出现了一个错误,导致你的应用程序重定向到/stamps并显示错误消息(这也意味着您的测试数据库实际上没有在测试之间重置,或者您显示的工厂正在创建嵌套记录,等等)
更新:重新阅读控制器代码后,我注意到您正在将201状态代码传递到重定向到201
实际上不会执行重定向-从重定向到文档-
请注意,状态代码必须是3xx HTTP代码,否则将导致重定向
不会发生
您的测试中有许多问题
首先,Capybara不应用于请求
规范中,而应用于功能/系统测试。一旦您确定不再需要将Capybara包括在每个RSpec测试中,并应从您的配置中删除config.include Capybara::DSL
(当您需要capybara/rspec
时,它会将capybara包含在测试类型中,它应该包含在-)
其次,单击按钮
不保证等待它触发的任何操作完成。因此,在尝试访问该操作创建的任何数据库对象之前,您需要等待可视页面更改(从技术上讲,您根本不应该在特性规范中直接访问数据库,但如果您打算…)
第三,正如@chumakoff所指出的,您不应该对Capybara使用静态匹配器,而应该使用Capybara提供的匹配器
click_button 'Create'
expect(page).to have_text('Stamp created!') # Whatever message is shown after creation
expect(page).to have_path(stamp_path(Stamp.first.id))
最后,你应该查看你的test.log
,并使用save_和_open_屏幕截图查看你的控制器实际做了什么-实际上,在创建时出现了一个错误,导致你的应用程序重定向到/stamps并显示错误消息(这也意味着您的测试数据库实际上没有在测试之间重置,或者您显示的工厂正在创建嵌套记录,等等)
更新:重新阅读控制器代码后,我注意到您正在将201状态代码传递到重定向到201
实际上不会执行重定向-从重定向到文档-
请注意,状态代码必须是3xx HTTP代码,否则将导致重定向
不会发生
对于其他来到这里的人,另一个可能的解决方案是增加您的等待时间。无论是全局还是每次单击
#全球
Capybara.default\u max\u wait\u time=5
#每次点击
查找(“我的按钮”)。单击(等待:5)
对于其他任何来到这里的人,另一个可能的解决方案是增加您的等待时间。无论是全局还是每次单击
#全球
Capybara.default\u max\u wait\u time=5
#每次点击
查找(“我的按钮”)。单击(等待:5)
您是否尝试过expect(第页)。拥有当前路径(stamp\u path(stamp.first.id))
?您是否尝试过expect(第页)。拥有当前路径(stamp\u path(stamp.first.id))
?感谢您详尽的回答。关于1,我很高兴地从
click_button 'Create'
expect(page).to have_text('Stamp created!') # Whatever message is shown after creation
# Now you can safely access the DB for the created stamp
click_button 'Create'
expect(page).to have_text('Stamp created!') # Whatever message is shown after creation
expect(page).to have_path(stamp_path(Stamp.first.id))