【发布时间】:2014-06-22 21:41:15
【问题描述】:
我遇到了一个非常奇怪的问题。我正在为我的 Rails 3.2.18 应用程序编写一些规范,我发现我的表单没有提交并且所有测试都失败了。
我正在使用
- Rails 3.2.18
- Rspec 2.13.0
- 水豚2.3.0
- Poltergeist 1.5.1
这是我的登录表单的(精简)示例:
<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name), html: { id: 'new_user_session' }) do |f| %>
<%= hidden_field_tag :redirect_to, URI(params[:redirect_to] || request.referer || request.env['PATH_INFO']).path %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :remember_me, as: :hidden, input_html: { value: 1 } %>
<%= f.submit t('sign_in') %>
<% end %>
这是功能规范:
require 'spec_helper'
feature 'Sign in' do
before do
@user = create(:user, email: 'user@example.com', password: 'supersecret', password_confirmation: 'supersecret')
@user.confirm!
end
scenario 'a registered user' do
visit '/home'
expect(page).to have_content I18n.t('sign_in')
expect(page).not_to have_content I18n.t('profile')
click_link I18n.t('sign_in')
expect(current_path).to eq('/users/sign_in')
expect(find('#redirect_to').value).to eq('/home')
within '#new_user_session' do
fill_in 'user_email', with: 'user@example.com'
fill_in 'user_password', with: 'supersecret'
click_button I18n.t('sign_in')
end
expect(current_path).to eq('/home')
expect(page).to have_content(I18n.t('devise.sessions.signed_in'))
expect(page).not_to have_content I18n.t('sign_in')
expect(page).to have_content I18n.t('profile')
end
end
测试失败,因为在填写表单并单击按钮后,current_path 不是预期的(我应该被重定向到主页)。
在日志中,我可以看到表单不是通过 POST 请求而是通过 GET 提交的(这是首次访问登录页面后的第二个):
Completed 200 OK in 164.1ms (Views: 161.7ms | ActiveRecord: 0.0ms)
Started GET "/users/sign_in" for 127.0.0.1 at 2014-06-22 23:25:23 +0200
Processing by Users::SessionsController#new as HTML
有趣的是,如果我从渲染页面复制并粘贴 HTML 代码并将其放入部分而不是 simple_form 帮助程序中,它可以工作,并且测试通过正确的 POST 请求通过!我也使用了 form_for 和 form_tag ,它也不起作用。这是生成的代码:
<form accept-charset="UTF-8" action="/users/sign_in" class="simple_form new_user" id="new_user_session" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="f8SGSa4y8l9imeaa9oJtsT0JShPw2NEaYOKfA/9IL0O0=" /></div>
<input id="redirect_to" name="redirect_to" type="hidden" value="/users/sign_in" />
<div class="input email optional user_email field_with_hint"><label class="email optional" for="user_email">Email</label><input class="string email optional" id="user_email" maxlength="255" name="user[email]" size="50" type="email" value="" /><span class="hint">Email</span></div>
<div class="input password optional user_password field_with_hint"><label class="password optional" for="user_password">Password</label><input class="password optional" id="user_password" maxlength="128" name="user[password]" size="50" type="password" /><span class="hint">Password</span></div>
<div class="input hidden user_remember_me"><input class="hidden" id="user_remember_me" name="user[remember_me]" type="hidden" value="1" /></div>
<input name="commit" type="submit" value="Login" />
</form>
我可以通过不同方式测试此功能(注册、重置密码和确认),但我想了解我的代码有什么问题。
编辑:这是来自 Rspec 的失败消息。我想它没有多大帮助,基本上它在检查 current_path 是否是 redirect_to 提供的路径时失败:
F
Failures:
1) Sign in a registered user
Failure/Error: expect(current_path).to eq('/home')
expected: "/home"
got: "/users/sign_in"
(compared using ==)
# ./spec/features/signin_spec.rb:29:in `block (2 levels) in <top (required)>'
Finished in 1.09 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/features/signin_spec.rb:10 # Sign in a registered user
它应该是 /home(设计重定向到 params[:redirect_to]),但它是 /users/sign_in,因为表单不是通过 POST 提交的,而是对同一路径的 GET(所以表单只是重新渲染)。
更新:我通过将 gem 版本升级到最新版本解决了这个问题。
- Rails 3.2.21
- Rspec 3.1.0
- 水豚2.4.4
- Poltergeist 1.5.1
【问题讨论】:
-
您能否发布当您的 rspec 示例失败时收到的错误消息。
-
我在原文中添加了失败信息。
-
@lucatironi,我遇到了同样的问题。你找到解决办法了吗?
-
我实际上是通过升级到上面列出的 gems 的最新版本解决了这个问题。
标签: ruby-on-rails forms capybara