我在进行集成测试时遇到麻烦,对于用户在我的rails应用程序中登录,传递。
我使用Rspec和capybara,以及设计用户身份验证
这是我的代码:
请求/ authentications_spec.rb
describe 'log in' do
before { visit root_path }
subject { page }
describe 'should be able to log in' do
before do
user = FactoryGirl.create(:user)
fill_in :user_email, with: user.email
fill_in :user_password, with: user.password
click_on 'Log in'
end
it { should have_link 'Log out' }
end
end
工厂/ user_factory.rb
FactoryGirl.define do
factory :user do
sequence( :first_name ) { |n| "FirstName#{n}" }
sequence( :last_name ) { |n| "LastName#{n}" }
sequence( :email ) { |n| "foo#{n}@example.com" }
password 'foobar'
password_confirmation 'foobar'
created_at Time.now
updated_at Time.now
end
end
_login_form.html.erb, 此表单在应用程序布局标题中呈现。
<%= form_for(resource, as: resource_name, url: session_path(resource_name), html: { id: 'login-mini-form' }) do |f| %>
<%= f.email_field :email, placeholder: 'Your email' %>
<%= f.password_field :password, placeholder: '******' %>
<%= f.submit "Log in", id: 'login-button' %>
<%- if devise_mapping.rememberable? -%>
<%= f.check_box :remember_me %> <%= f.label :remember_me %>
<%- end -%>
<% end %>
在布局中我有类似的东西:
if user_signed_in?
render 'devise/menu/logout_button'
else
render 'devise/menu/login_form'
end
测试给了我
1) User should be able to log in with valid credentials
Failure/Error: it { should have_link 'Log out' }
expected link "Log out" to return something
# ./spec/requests/authentications_spec.rb:117:in `block (6 levels) in <top (required)>'
Finished in 0.71406 seconds
8 examples, 2 failures, 2 pending
我不知道为什么我的测试没有通过。有什么想法吗?
非常感谢!
编辑:我在测试注册时遇到了相同的行为:expect { click_button register_button }.to change(User, :count).by 1
,测试返回:
Failure/Error: expect { click_button register_button }.to change(User, :count).by 1
count should have been changed by 1, but was changed by 0
答案 0 :(得分:1)
所以,我发现了什么不起作用:
describe 'log in' do
before { visit root_path }
subject { page }
describe 'should be able to log in' do
before do
user = FactoryGirl.create(:user)
fill_in :user_email, with: user.email
fill_in :user_password, with: user.password
click_on 'Log in'
end
it { should have_link 'Log out' }
end
事实上正确的代码是:
describe 'log in' do
before { visit root_path }
subject { page }
describe 'should be able to log in' do
before do
user = FactoryGirl.create(:user)
fill_in 'user_email', with: user.email
fill_in 'user_password', with: user.password
click_on 'Log in'
end
it { should have_link 'Log out' }
end
end
end
似乎Capybara fill_in方法不会将符号作为id的参数,而只是字符串。 傻我。
答案 1 :(得分:0)
您没有提供您期望的主题,因此看起来RSpec正在使用最后一个表达式的结果。最后一个表达式是你的click_button
,它不会返回任何内容。你什么都不能打电话给should
。
要解决此问题,您只需指定页面应具有所述链接即可。我使用Capybara和Selenium-Webdriver,所以对我来说它看起来像page.should have_link...
。我的RSpec-fu不够强大,无法知道您是否应该使用page
,或者替换response
,session
或其他内容。