使用rspec / devise登录集成测试

时间:2012-07-03 23:13:25

标签: ruby-on-rails ruby-on-rails-3 rspec devise

我在进行集成测试时遇到麻烦,对于用户在我的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

2 个答案:

答案 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,或者替换responsesession或其他内容。