#ruby-on-rails #devise #cucumber #integration-testing
#ruby-on-rails #разработка #cucumber #интеграция-тестирование
Вопрос:
Примечание: Я очень новичок в Cucumber.
Я пытаюсь сделать обобщенный шаг (не уверен, существует ли он где-то уже или нет), чтобы вы могли легко добавлять объекты к другому объекту, учитывая, что ассоциация существует. Я хочу сделать что-то вроде:
manage_notes.функция
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
Итак, вы можете видеть, что в моем «фоновом режиме» пользователь создается с помощью фабрики, а затем входит в систему через мой интерфейс. Я хочу получить доступ к модели этого вошедшего в систему пользователя.
Ответ №1:
Я не использую 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
.
Не говоря уже о том, что это может привести к путанице при чтении, некоторые люди могут подумать, что вы добавляете примечание пользователю, который, как они теперь могут знать (или осознавать), на самом деле вы.
Хотя вам все равно придется ссылаться явно (например. user: «John Doe»), я думаю, что это плюс. Всегда вызывая определенные ссылки, все знают, на кого ссылаются, и нет вопросов о том, кто что для чего делает.
Pickle очень хорошо подходит для этой цели. Единственные проблемные области, которые мы находим, связаны с вещами, созданными непосредственно через пользовательский интерфейс приложения, что становится немного сложнее, чтобы убедиться, что вы создаете правильную ссылку на него.
Pickle имеет большое количество применений, поэтому обязательно взгляните.
Обновление
Вам придется найти себя здесь. Поскольку, как вы и хотели, 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. Спасибо, я ценю время, которое вы потратили на это. Я пометил это как полезное. Я рассмотрю это более подробно в более удобное время и определю, подходит ли это для меня.
2. Хорошо, вы абсолютно правы в том, что я должен удалить часть «которая принадлежит пользователю:». Но как мне получить доступ к «мне»? Я хочу сделать «Я уже создал заметку». На моем этапе я мог бы использовать ‘Учитывая, что существует заметка с содержимым: «Привет», но как бы я назначил user_id для пользователя, вошедшего в систему?
3. Я думаю, что у меня самая сложная попытка выяснить, кто такой «я» в моих шагах. Я могу сделать ‘Я вошел в систему как ‘электронная почта’ с паролем ‘password’ просто отлично. Но затем, когда я хочу сделать «Я уже создал заметку», как мне получить ссылку на вошедшего в систему пользователя?
4. Я обновил ответ, чтобы дать вам пример того, как найти себя (или, по крайней мере, как бы я нашел себя). Вам придется управлять тем, кто этот «я», с помощью ваших тестов. Либо через gem, подобный
pickle
, либо другим способом. Извините за поздний ответ, нужно принести домой бекон.5. Я понимаю, что вы имеете в виду, ха-ха, никаких проблем с поздним ответом. Просто не кажется хорошей идеей жестко кодировать электронное письмо на пользовательском шаге. Если мне нужно изменить адрес электронной почты в моем «фоновом режиме» функции, тогда мне пришлось бы изменить его в нескольких местах. Вы понимаете?
Ответ №2:
Я просто решаю это очень просто: у меня есть «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 в своих шагах
Ответ №3:
Эта тема довольно старая, но вот решение, которое я использую. Вы должны загрузить этот модуль, например, в 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)
Ответ №4:
Вы должны иметь возможность использовать контекст для этого: http://cuke4ninja.com/sec_sharing_context.html
Есть шаг, на котором вы входите в систему как пользователь, сохраняете его в общем контексте, доступном для всех шагов, а затем просто получаете к нему доступ в следующих шагах.
Надеюсь, что это делает шаги, и я не неправильно истолковал вопрос.
Удачи с этим!
Комментарии:
1. Из вашего описания это звучит как нечто, что просто запускается перед каждым сценарием, не так ли? Это не совсем то, чего я хочу. У меня уже есть фоновый режим, который запускается перед каждым шагом, в этом фоновом режиме пользователь входит в систему. Я просто не уверен, как «получить доступ» к пользовательской модели пользователя, который в данный момент вошел в систему. В разработке я могу просто вызвать «current_user».
2. Я не уверен, что это то, чего я хочу, если я не неправильно понимаю.
3. Способ, которым это работает на java (я использовал только реализацию Java), заключается в том, что вы определяете контекст, который будет вводиться на каждом шаге. Итак, на первом шаге входа в систему вы выполняете шаги входа в систему и устанавливаете свою переменную current_user, и из этого контекстного объекта, который доступен для каждого другого шага, вы можете затем ссылаться на переменную current_user. Помогает ли это?
4. Я еще раз рассмотрю это на работе завтра. Я чувствую, что есть более простой способ. Вы работали с Rails / Devise раньше?
5. Теперь ссылка ведет на веб-сайт с рекомендациями по знакомствам: (