简体   繁体   English

我如何为Rspec做一个登录助手?

[英]How do i make a login helper for Rspec?

Hello i have about 50 rspec tests i need to write. 您好,我需要编写约50个rspec测试。 There's no gem that was used for the user model. 没有用于用户模型的gem。 It was created from scratch. 它是从头开始创建的。 How does someone make a login helper for rspec? 有人如何为rspec做登录助手?

Please keep in mind this is for Rspec not capybara 请记住,这是针对Rspec而不是水豚

Thank you. 谢谢。

Here is the sessions controller 这是会话控制器

class SessionsController < ApplicationController SessionsController类<ApplicationController

  def new
  end

  def create
    user = User.find_by(email: params[:sessions][:email].downcase)
    if user && user.authenticate(params[:sessions][:password])
      if user.activated?
        log_in user
        params[:sessions][:remember_me] == '1' ? remember(user) : forget(user)
        redirect_back_or user
      else
        message  = "Account not activated. "
        message += "Check your email for the activation link."
        flash[:warning] = message
        redirect_to root_url
      end
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    log_out if logged_in?
    redirect_to root_url
  end
end

Here is the sessions helper 这是会议助手

module SessionsHelper

  # Logs in the given user.
  def log_in(user)
    session[:user_id] = user.id
  end

  # Returns the user corresponding to the remember token cookie.
  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

  # Returns true if the user is logged in, false otherwise.
  def logged_in?
    !current_user.nil?
  end

  # Logs out the current user.
  def log_out
    session.delete(:user_id)
    @current_user = nil
  end

  # Remembers a user in a persistent session.
  def remember(user)
    user.remember
    cookies.permanent.signed[:user_id] = user.id
    cookies.permanent[:remember_token] = user.remember_token
  end

  # Returns true if the given user is the current user.
  def current_user?(user)
    user == current_user
  end

  # Forgets a persistent session.
  def forget(user)
    user.forget
    cookies.delete(:user_id)
    cookies.delete(:remember_token)
  end

  # Logs out the current user.
  def log_out
    forget(current_user)
    session.delete(:user_id)
    @current_user = nil
  end

  # Redirects to stored location (or to the default).
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
  end

  # Stores the URL trying to be accessed.
  def store_location
    session[:forwarding_url] = request.url if request.get?
  end
end

Here is a user controller spec that i have. 这是我拥有的用户控制器规格。 Problem is i don't have a login(user) helper method. 问题是我没有登录(用户)帮助器方法。 Does anyone know how to write one? 有人会写吗? I have looked this up and couldn't find much information about it. 我查了一下,找不到更多的信息。

require "rails_helper" require "test_helper" 要求“ rails_helper”要求“ test_helper”

RSpec.describe UsersController, type: :controller do
  let!(:admin) { create(:user, password: "Password123", admin: true) }
  let!(:user) { create(:user, password: "Password456", admin: false) }

  let!(:update_params) do
    { id: user.id, user_id: user.id, user: user }
  end

  let!(:users) do
    [admin, user] + 3.times.map { create(:user) }
  end

  let!(:user_params) { user_params = { username: "username#{rand(1000)}",
                                       email: "user#{rand(1000)}@factory.com",
                                       password: "Password123",
                                       password_confirmation: "Password123",
                                       admin: false,
                                       description: "Nihil eligendi ab debitis iure.",
                                      } }

  let!(:category) { create(:category, name: "Shirt") }
  let!(:category1) { create(:category, name: "Short") }

  describe "GET #index" do
    it "admin user renders template and shows users" do
      get :index, {}, { user_id: admin.id }
      expect(response).to render_template(:index)
      expect(response).to have_http_status(:success)
      expect(assigns(:users).map(&:id)).to eq users.map(&:id)
    end

    it "user renders template and shows users" do
      get :index, {}, { user_id: user.id }
      expect(response).to redirect_to(root_path)
    end

    it "redirects visitor" do
      get :index
      expect(response).to redirect_to(root_path)
    end
  end

  describe "GET #show" do
    it "user renders template and shows user" do
      get :show, id: user.id
      expect(response).to render_template(:show)
      expect(response).to have_http_status(:success)
      expect(assigns(:user)).to eq(user)
    end
  end

  describe "GET #new" do
    it "renders template" do
      get :new
      expect(response).to render_template(:new)
      expect(response).to have_http_status(:success)
    end
  end

  describe "POST #create" do
    it "user created" do
      post :create, user: user_params
      expect(assigns(:user)).to be_persisted
    end
  end

  describe "GET #edit" do
    it "user edit" do
      get :edit, {id: user.id }, { user_id: user.id }
      expect(response).to render_template(:edit)
      expect(response).to have_http_status(:success)
      expect(assigns(:user)).to eq(user)
    end
  end

  describe "POST #update" do
    it "user updated" do
      patch :update, update_params
      expect(response).to redirect_to(assigns(:user))
      expect(assigns(:user)).to eq(user)
    end
  end

  # describe "DELETE #destroy" do
  #   it "user destroy" do
  #     delete :destroy, {id: user.id }, { user_id: user.id }, user: user_params
  #     expect(response).to redirect_to(users_path)
  #   end
  # end
end

When i run the above test i receive this error 当我运行上述测试时,我收到此错误

  2) UsersController POST #update user updated
     Failure/Error: expect(response).to redirect_to(assigns(:user))
       Expected response to be a redirect to <http://test.host/users/1046959425> but was a redirect to <http://test.host/login>.
       Expected "http://test.host/users/1046959425" to be === "http://test.host/login".

It is because my user isn't logged in. It would be great to have a login helper method that will login the user in a before do end. 这是因为我的用户尚未登录。最好有一个登录帮助程序方法,该方法将在结束之前登录用户。

I have implemented some user login related methods for my tests in my test_helper.rb , it looks like this: 我已经在test_helper.rb为测试实现了一些与用户登录相关的方法,如下所示:

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Returns true if a test user is logged in.
  def is_logged_in?
    !session[:user_id].nil?
  end

  # Logs in a test user.
  def log_in_as(user, options = {})
    password    = options[:password]    || 'password'
    remember_me = options[:remember_me] || '1'
    if integration_test?
      post login_path, session: { email:       user.email,
                                  password:    password,
                                  remember_me: remember_me }
    else
      session[:user_id] = user.id
    end
  end

  private

  # Returns true inside an integration test.
  def integration_test?
    defined?(post_via_redirect)
  end
end

It has log_in_as method that takes an user and you can use that in your test. 它具有带用户的log_in_as方法,您可以在测试中使用它。 eg: 例如:

  describe "POST #update" do
    it "user updated" do
      log_in_as user # now you have log_in_as method implemented
      patch :update, update_params
      expect(response).to redirect_to(assigns(:user))
      expect(assigns(:user)).to eq(user)
    end
  end

You may need to make some modifications of the above code in order to make it work in your application but it should give you a clear idea on how to do that. 您可能需要对上面的代码进行一些修改,以使其在您的应用程序中起作用,但是它应该使您对如何执行此操作有一个清晰的了解。 I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM