Переменные сеанса с Огуречными Историями

Спасибо за справку everyones. Я нашел что-то, что показало мне, как сделать это с Perl и портировало его к рубину. Я имею занесенный в блог об этом для тех, которые ищут решение

16
задан Simone Carletti 18 August 2009 в 13:15
поделиться

6 ответов

mocks плохи в сценариях с огурцом - они почти что-то вроде антипаттерна.

Я предлагаю написать шаг, который фактически выполняет вход пользователя в систему. Я делаю это таким образом

Given I am logged in as "auser@example.com"

Given /^I am logged in as "(.*)"$/ do |email|
  @user = Factory(:user, :email => email)
  @user.activate!
  visit("/session/new")
  fill_in("email", :with => @user.email)
  fill_in("password", :with => @user.password)
  click_button("Sign In")
end

] Я понимаю, что переменная экземпляра @user является плохим тоном, но я думаю, что в случае входа / выхода наличие @user определенно полезно.

Иногда я называю это @current_user .

19
ответ дан 30 November 2019 в 15:06
поделиться

Я повторю danpickett, говоря, что в Cucumber следует по возможности избегать mock'ов. Однако, если в вашем приложении нет страницы входа или, возможно, производительность является проблемой, тогда может потребоваться прямая имитация входа в систему.

Это уродливый хакер, но он должен выполнить свою работу.

Given /^I am logged in as "(.*)"$/ do |email|
  @current_user = Factory(:user, :email => email)
  cookies[:stub_user_id] = @current_user.id
end

# in application controller
class ApplicationController < ActionController::Base
  if Rails.env.test?
    prepend_before_filter :stub_current_user
    def stub_current_user
      session[:user_id] = cookies[:stub_user_id] if cookies[:stub_user_id]
    end
  end
end
25
ответ дан 30 November 2019 в 15:06
поделиться

Насколько я понимаю, вы получаете:

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.session (NoMethodError)

при доступе к сеансу [] до того, как запрос был создан. В вашем случае, я предполагаю, что если вы поместите webrats ' visit some_existing_path перед доступом к session [] в вашем определении шага, ошибка исчезнет.

Теперь, к сожалению, сеанс не сохраняется между этапами (по крайней мере, я не мог найти способ), поэтому эта информация не помогает ответить на ваш вопрос :)

Итак, я предположим, сеанс Райана [: user_id] = cookies [: stub_user_id] ... это путь. Хотя, я думаю, код, связанный с тестированием, в самом приложении звучит неправильно.

3
ответ дан 30 November 2019 в 15:06
поделиться

I don't know how much this relates to the original question anymore, but I decided to post anyway in the spirit of discussion...

We have a cucumber test suite that takes > 10 minutes to run so we wanted to do some optimization. In our app the login process triggers a LOT of extra functionality that is irrelevant to majority of the scenarios, so we wanted to skip that by setting the session user id directly.

Ryanb's approach above worked nicely, except that we were unable to log out using that approach. This made our multi-user stories fail.

We ended up creating a "quick login" route that is only enabled in test environment:

# in routes.rb
map.connect '/quick_login/:login', :controller => 'logins', :action => 'quick_login'

Here is the corresponding action that creates the session variable:

# in logins_controller.rb
class LoginsController < ApplicationController
  # This is a utility method for selenium/webrat tests to speed up & simplify the process of logging in.
  # Please never make this method usable in production/staging environments.
  def quick_login
    raise "quick login only works in cucumber environment! it's meant for acceptance tests only" unless Rails.env.test?
    u = User.find_by_login(params[:login])
    if u
      session[:user_id] = u.id
      render :text => "assumed identity of #{u.login}"
    else
      raise "failed to assume identity"
    end
  end
end

For us this ended up being simpler than working with the cookies array. As a bonus, this approach also works with Selenium/Watir.

Downside is that we're including test-related code in our application. Personally I don't think that adding code to make application more testable is a huge sin, even if it does add a bit of clutter. Perhaps the biggest problem is that future test authors need to figure out which type of login they should use. With unlimited hardware performance we obviously wouldn't be doing any of this.

5
ответ дан 30 November 2019 в 15:06
поделиться

RE. Решение Райана - вы можете открыть действие ActionController в вашем файле Env.RB и поместите его, чтобы избежать положить в основу производственного кода (благодаря базе John @ Pivotal)

# in features/support/env.rb
class ApplicationController < ActionController::Base
  prepend_before_filter :stub_current_user
  def stub_current_user
    session[:user_id] = cookies[:stub_user_id] if cookies[:stub_user_id]
  end
end
17
ответ дан 30 November 2019 в 15:06
поделиться

Я использую решение для входа только для тестирования, как у Prikka, но я делаю все это в Rack вместо того, чтобы создавать новый контроллер и маршруты.

# in config/environments/cucumber.rb:

config.middleware.use (Class.new do
  def initialize(app); @app = app; end
  def call(env)
    request = ::Rack::Request.new(env)
    if request.params.has_key?('signed_in_user_id')
      request.session[:current_user_id] = request.params['signed_in_user_id']
    end
    @app.call env
  end
end)

# in features/step_definitions/authentication_steps.rb:
Given /^I am signed in as ([^\"]+)$/ do |name|
  user = User.find_by_username(name) || Factory(:user, :username => name)
  sign_in_as user
end

# in features/step_definitions/authentication_steps.rb:
Given /^I am not signed in$/ do
  sign_in_as nil
end

module AuthenticationHelpers
  def sign_in_as(user)
    return if @current_user == user
    @current_user = user
    get '/', { 'signed_in_user_id' => (user ? user.to_param : '') }
  end
end

World(AuthenticationHelpers)
2
ответ дан 30 November 2019 в 15:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: