访问Cucumber功能中的当前用户 - 设计

时间:2011-06-10 12:56:35

标签: ruby-on-rails devise cucumber integration-testing

注意:我对Cucumber很新。

我正在尝试进行一般化步骤(不确定某个地方是否已经存在),以便在存在关联的情况下,您可以轻松地将对象添加到另一个对象。我想做点什么:

manage_notes.feature

Background: Login User
  Given the following user records
    | email          | password |
    | test@email.com | password |
  Given I am logged in as "test@email.com" with password "password"

Scenario: Edit existing note
  Given I have already created a note that belongs to current_user

general_steps.rb

Given /^the following (.+) records?$/ do |factory, table|
  table.hashes.each do |hash|
    Factory(factory, hash)
  end
end

Given /^I am logged in as "([^\"]*)" with password "([^\"]*)"$/ do |email, password|
  unless email.blank?
    visit new_user_session_path
    fill_in "Email", :with => email
    fill_in "Password", :with => password
    click_button "Sign In"
  end
end

note_steps.rb

  Given /^I have already created a (.+) that belongs to (.+)$/ do |factory, resource|
      model = Factory(factory)
      resource.send(model.class.to_s.downcase.pluralize) << model
  end

似乎可能有办法使用设计'current_user'帮助器。

访问登录用户的正确方法是什么?

如果您需要更多信息,请与我们联系。 谢谢!

更新1: 我通过创建允许我这样做的新步骤暂时解决了我的问题:

Given I have already created a note that is owned by the user with email "test@email.com"

但我不想指定电子邮件,我仍然希望能够使用登录用户。

更新2: 添加了general_steps.rb

所以你可以看到,在我的'Background'中,用户是通过Factory创建的,然后通过我的界面登录。我想访问登录用户的模型。

4 个答案:

答案 0 :(得分:3)

我不使用Devise,因此如果Devise有访问current_user的方法,我无法专门回答。

但我实际上喜欢使用Pickle来帮助我保留我的参考资料。也许这可以帮助你,直到你找到更具设计性的方式来实现你想要的东西。

Given /^the following (.+) records$/ do |factory, table|
  table.hashes.each do |hash|
    Factory(factory, hash)

    # since this is like an all encompassing factory creator, this line to 
    # create a Pickle references might need a bit more extra work if you want
    # to create references for other factory types

    # I assume email is unique, else use a unique identifier of some sort
    find_model! %{user: "#{hash['email']}"}, {:email => hash['email']} 
  end
end

Given /^I have already created a (.+) that belongs to #{capture_model}$/ do |factory, name|
  model = Factory(factory)
  ref = model!(name) # we find that reference here
  ref.send(model.class.to_s.downcase.pluralize) << model
end

这将读取

Given I have already created a note that belongs to user: "test@email.com"

# I would just change this to 
Given I have already created a note

# or
Given a note was created for user: "test@email.com"

您是I,因为您说Given I logged in...,无需说that belongs to user: "test@email.com"它已经you

更不用说当你阅读它时可能会引起混淆,有些人可能会认为你正在向用户添加一个注释,他们现在可能知道(或意识到)实际上就是你自己。


虽然你仍然需要明确引用(例如用户:“John Doe”),但我认为这是一个加分。通过始终调用特定的引用,每个人都知道谁被引用,并且毫无疑问谁在做什么。

Pickle为此目的很好地为我们服务。我们发现的唯一有问题的区域是直接通过应用程序的ui创建的东西,这有点难以确保您创建对它的正确引用。

Pickle有很多用途,所以一定要看看。


<强> Upate

你必须在这里找到自己。因为,就像你想要的那样,没有current_user选项(就我们所知)。所以你基本上必须在这个场景中找到“演员”。

Given /^I have already created a note$/ do
  user = model!(%{user: "test@email.com"}) # if using pickle
  # user = User.find_by_email("test@email.com") # if just regular AR
  user.notes << Note.create
end

答案 1 :(得分:3)

我只是解决它很简单: 我有“FactoryGirl”用户定义,然后这个方法...

Given(/^I am users logged in as "(.*?)" with password "(.*?)"$/) do |email, pass|
  visit new_user_session_path
  fill_in "user_email", :with => email
  fill_in "user_password", :with => pass
  click_button I18n.t("login.sign_in")
  @current_user = User.find_by_email(email)
end

进一步了解您可以在步骤中使用@current_user

答案 2 :(得分:2)

这个主题很老了,但这是我使用的解决方案。例如,您必须在env.rb中加载此模块。使用它,您可以在步骤中使用@current_user或current_user访问当前用户。

module UserSessionHelper
  def current_user
    @current_user
  end

  def login(user=nil)
    if user.nil?
      @current_user = FactoryGirl.create(:user, username: fake_name)
    else
      @current_user = user
    end
    visit login_path
    fill_in 'Username', with: @current_user.username
    fill_in 'Password', with: '1234'
    click_button 'Login'
    page.should have_content('Logout')
  end

  def logout
    click_link 'Logout'
  end
end

RSpec.configure do |config|
  config.include UserSessionHelper
end if RSpec.respond_to?(:configure)

World(UserSessionHelper) if respond_to?(:World)

答案 3 :(得分:1)

您应该可以使用上下文: http://cuke4ninja.com/sec_sharing_context.html

有一个以用户身份登录的步骤,将其存储在可供所有步骤访问的共享上下文中,然后只需按照以下步骤访问它。

希望这会产生一些步骤,但我没有误解这个问题。

祝你好运!