Ответ 1
Также работает
user = create(:user) #FactoryBot
allow(controller).to receive(:current_user).and_return(user)
У меня есть контроллер на основе MHartl RoR4 Tutorial
И так же, как MHartl, я не использую Devise, я развернул свою собственную систему аутентификации
Возникли проблемы с RSpec для UsersController#Edit
, поскольку представление имеет вызов current_user.admin?
, а контроллер вызывает @path_switch = path_switch
Я продолжаю получать ошибки RSpec по типу:
1) User Pages Edit
Failure/Error: visit edit_user_path(user)
NoMethodError:
undefined method 'admin?' for nil:NilClass
# ./app/controllers/users_controller.rb:106:in 'path_switch'
# ./app/controllers/users_controller.rb:53:in 'edit'
# ./spec/requests/user_pages_spec.rb:54:in 'block (3 levels) in <top (required)>'
UsersController:
class UsersController < ApplicationController
...
def edit
@user = User.find(params[:id])
@path_switch ||= path_switch #error
end
...
def path_switch
if current_user.admin? #error
users_path
else
root_path
end
end
end
Я нашел эту действительно полезную статью, которая вселяет надежду, что я на правильном пути, но не могу заставить ее работать.
Здесь, насколько я получил (обновлено):
user_pages_spec.rb:
require 'spec_helper'
require 'support/utilities'
describe "User Pages" do
#include SessionsHelper
let(:user) { FactoryGirl.create(:user) }
let(:current_user) {user}
subject { page }
describe "Edit" do
before do
sign_in(user)
visit edit_user_path(user)
end
it '(check links and content)' do
should have_button('Submit')
should have_link('Cancel')
should have_content(user.fname+"\ profile")
end
...
end
...
end
Но current_user
все еще возвращается nil
Любая помощь/руководство приветствуется. Спасибо!
Добавление include SessionsHelper
в верхний блок описания моего user_pages_edit.rb
, похоже, пытается использовать sign_in (путь) от этого помощника. Создание проблемы между RSpec и cookies.permanent
. Так что перебор.
к сожалению, это возвращает меня к моей ошибке .admin?
.
Есть два вызова current_user.admin?
Один из них находится в контроллере:
def path_switch
if current_user.admin? #error current_user == nil
users_path
else
root_path
end
end
Один вид как ERB:
<% if current_user.admin? %>
<div class="row col-xs-6 col-sm-6 col-md-3">
<div class="input-group input-selector">
...
Все, что мне нужно сделать, это выяснить, как установить current_user.admin = true
и передать его контроллеру (а затем, надеюсь, представлению), чтобы страница могла загружаться.
Для этого все, что мне нужно сделать, это установить current_user = user
, потому что user.admin == true
.
Также работает
user = create(:user) #FactoryBot
allow(controller).to receive(:current_user).and_return(user)
Если вы выполняете модульное тестирование вашего контроллера, вы можете просто заглушить current_user
в блоке до этого, например:
let(:user) { ... }
# RSpec version <= 2 syntax:
before { controller.stub(:current_user) { user } }
# RSpec version >= 3 syntax:
before { allow(controller).to receive(:current_user) { user } }
Если вы выполняете функцию или запрашиваете тестирование, я советую вам выполнить реальный вход в систему, создав пользователя в своей базе данных, а затем пройдя через страницу входа с этими учетными данными пользователя
Здесь вы, кажется, выполняете тест функции, вы должны написать помощника, который выполняет создание пользовательской записи и проходит через вход.
Кроме того, при тестировании функций, чтобы получить много времени при запуске теста, не стесняйтесь группировать свои утверждения в том же блоке. Очевидно, вместо:
it { should have_button('Submit')}
it { should have_link('Cancel')}
it { should have_content(user.fname+"\ profile")}
Вы можете написать
it 'check links and content' do
should have_button('Submit')
should have_link('Cancel')
should have_content(user.fname+"\ profile")
end
Это позволит избежать нескольких сеансов вашей функциональной среды, а также для входа в систему несколько раз
Для меня работала с:
before { controller.stub!(:current_user).and_return(user) }
Я столкнулся с той же проблемой с унаследованным приложением Rails 4 и основал свое решение на этом тестовом примере Rspec Views.
Сначала определите помощник, который определит отсутствующий вспомогательный метод в экземпляре контроллера
# /spec/support/concerns/view_helper.rb
module ViewHelper
def include_current_user_helper(&block)
controller.singleton_class.class_eval do
define_method :current_user, &block
helper_method :current_user
end
end
end
Затем настройте Rspec для включения его во все помощники вида
# spec/rails_helper.rb
# ...
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
RSpec.configure do |config|
# ...
config.include ViewHelper, type: :view
end
И в спецификации вида это называется так
RSpec.describe 'something' do
let!(:user) { FactoryGirl.create(:user) } # Note the "!" there
before { include_current_user_helper { user } }
# do stuff
end
Примечание: вызов let
с грохотом важен, так как содержимое внутри блока будет выполняться лениво, вне области тестирования, и пользователь будет нулевым, если нет