【问题标题】:Rspec test error in devise session #create设计会话#create中的Rspec测试错误
【发布时间】:2016-12-26 10:56:27
【问题描述】:

我实现了积分系统。当他登录时,User.point 增加 2。 我的设计会话控制器如下。

     class Users::SessionsController < Devise::SessionsController
            after_action :add_point, only: [:create]
             # POST /resource/sign_in
             def create
               super
             end
            private

          def add_point
              resource.rewards.create(point: 2)
         end

      end

我的规范/控制器/users_controller_spec.rb 如下。

RSpec.describe UsersController, type: :controller do
 describe 'adds 2 point with login' do
  before do
      @user=create(:user)
  end
  it 'adds 2 point in one day if two times login' do
    expect{login_user(@user)}.to change {@user.points}.by(0)
  end
  it 'adds 4 point in two day ' do
    expect{login_user(@user)}.to change {@user.points}.by(2)
  end
 end 
end

下面是我的模型/user.rb。

      class User < ActiveRecord::Base
             def points
              self.rewards.sum(:point)
             end
      end

当我执行 rspec 命令时,我遇到了这个错误。

    Failure/Error: expect{login_user(@user)}.to change {@user.points}.by(2)
   expected result to have changed by 2, but was changed by 0

我确认@user.points 在 rails/console 中增加了 2。 为什么我有这个错误?请告诉我。

通过查看答案,我将其更改为下面。

      require 'rails_helper'

      RSpec.describe Users::SessionsController, type: :controller do
       describe 'adds 2 point with login' do
         before do
          @user=create(:user)
          @request.env["devise.mapping"] = Devise.mappings[:user]
        end
        it 'adds 2 point in one day if two times login' do
         expect{post :create, params: {email: @user.email ,password: @user.password} }.to change {@user.points(true)}.by(0)
  end
        it 'adds 4 point in two day ' do
          expect{post :create, params: {email: @user.email ,password: @user.password} }.to change {@user.points(true)}.by(2)
       end
     end
    end

【问题讨论】:

    标签: ruby-on-rails ruby rspec devise


    【解决方案1】:

    首先,您是否配置了路由,因为您使用了自定义控制器(尽管它继承自 Devise Session 控制器)?

    类似这样,但在你的情况下,它是会话而不是注册:

    devise_for :users, :controllers => { :registrations => "registrations" }
    

    来源: https://howilearnedrails.wordpress.com/2013/12/27/how-to-override-and-customize-the-devise-controller-in-rails/comment-page-1/

    其次,由于您基本上使用的是自定义控制器,因此请尝试以正常方式点击控制器,而不是使用 Devise 测试助手。 假设您从 Devise 文档中获得了 login_user 方法,如下所示:

    module ControllerMacros   
      def login_user
        before(:each) do
          @request.env["devise.mapping"] = Devise.mappings[:user]
          user = FactoryGirl.create(:user)
          user.confirm! # or set a confirmed_at inside the factory. Only necessary if you are using the "confirmable" module
          sign_in user
        end
      end
    end
    

    您必须了解 login_user 方法不会向您创建的 Users::SessionsController 发出请求。这就是为什么您的回调after_action :add_point, only: [:create] 没有被触发,因此没有向logged_in 用户添加任何积分。

    我的意思是用正确的请求点击 rspec 是这样调用的:

    post :create, params: { session_params }
    

    【讨论】:

    • 感谢您的评论!我更改了 spec file ,并在这个问题中展示了它。但它不起作用。我有同样的错误...
    【解决方案2】:

    在大多数情况下都可以:

    expect{ login_user(@user) }.to change { @user.reload.points }.by(0)
    

    看起来@user 实例与 DB 不同步。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多