如何为Rspec制作登录助手?

时间:2015-10-11 00:37:36

标签: ruby-on-rails ruby ruby-on-rails-4 rspec

您好我需要写大约50个rspec测试。没有用于用户模型的gem。它是从头开始创建的。如何为rspec创建登录助手?

请记住这是针对Rspec而不是水豚

谢谢。

这是会话控制器

class SessionsController< ApplicationController中

zip "/Applications/Sublime Text.app/Contents/MacOS/Packages/Default.sublime-package" new_templates.py

这是会议助手

  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

这是我拥有的用户控制器规范。问题是我没有登录(用户)帮助方法。有谁知道如何写一个?我查了一下,找不到有关它的更多信息。

需要“rails_helper” 需要“test_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

当我运行上述测试时,我收到此错误

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

这是因为我的用户没有登录。拥有一个登录帮助程序方法会很棒,它会在之前登录用户。

1 个答案:

答案 0 :(得分:1)

我已在我的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

它有log_in_as方法,可以吸引用户,您可以在测试中使用它。 e.g:

  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

您可能需要对上述代码进行一些修改才能使其在您的应用程序中运行,但它应该让您清楚地了解如何执行此操作。我希望这会有所帮助。