我根据其feature_spec设置了一个简单的控制器:
stamps_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), 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
specs / requests / stamps_request_spec.rb
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
水豚会自动跟随所有重定向,并提交与按钮关联的表单。
但这在测试中不会发生,而是会引发错误:
预期:“ / stamps / 1
得到:“ /印章”
结果显而易见:它成功创建了图章,但无法重定向到新图章。我也使用binding.pry
确认了这一点。
侧注:
support / capybara.rb
require 'capybara/rails'
require 'capybara/rspec'
Capybara.server = :puma
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :firefox, marionette: true)
end
Capybara.javascript_driver = :selenium
RSpec.configure do |config|
config.include Capybara::DSL
end
spec_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
require 'rspec/rails'
require 'factory_bot_rails'
require 'pundit/matchers'
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
RSpec.configure do |config|
# .
# unrelated stuff
# .
end
答案 0 :(得分:1)
问题可能是提交表单后current_path
会花费一些时间。如果将sleep(x)
放在expect(current_path)
之前,您的代码将起作用。
相反,您应该使用具有所谓“等待行为”的方法,例如has_current_path?
,have_current_path
,assert_current_path
:
expect(page).to have_current_path(stamp_path(Stamp.first.id))
或
expect(page.has_current_path?(stamp_path(Stamp.first.id))).to eq true
答案 1 :(得分:1)
您的测试中存在许多问题。
首先,Capybara并不是要在request
规范-https://relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec中使用,而应与功能/系统测试一起使用。修复问题后,您不再需要将Capybara包含在每个RSpec测试中,而应从配置中删除config.include Capybara::DSL
(当您需要capybara/rspec
时,应将Capybara包含在测试类型中)在-https://github.com/teamcapybara/capybara/blob/master/lib/capybara/rspec.rb#L10)
第二,不能保证click_button
等待它触发的任何操作完成。因此,您需要等待可视页面更改,然后再尝试访问由该操作创建的任何数据库对象(从技术上讲,您实际上根本不应该在功能规格中进行直接的数据库访问,但是如果要...)
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
第三,如@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_and_open_screenshot
来查看您的控制器实际执行的操作-实际上,在创建过程中会引发错误,导致您的应用重定向到/ stamps并显示错误消息(也暗示您的测试数据库实际上没有在测试之间重置,或者您显示的工厂正在创建嵌套记录等)。
更新:重新读取您的控制器代码后,我注意到您正在向redirect_to
传递201状态代码。 201
实际上不会进行重定向-来自redirect_to
文档-https://api.rubyonrails.org/classes/ActionController/Redirecting.html#method-i-redirect_to
请注意,状态码必须是3xx HTTP代码,否则重定向将 不会发生。
答案 2 :(得分:0)
对于来到这里的其他人,另一种可能的解决方案是增加您的等待时间。全局或每次点击
testlist= ['brioche','sandwich','bread,','shrimp,','peeled,','tail','fan','attached,','butter','dill','shallot','Equipment:','cups']