设计注册操作中的 Rspec 错误



我实现积分系统。当用户创建时,用户有一些点。我的registrations_controller_spec.rb在下面。

         require 'rails_helper'
         RSpec.describe Users::RegistrationsController, type: :controller do
           describe 'sign in' do
            before do
              @user=build(:user)
              @request.env["devise.mapping"] = Devise.mappings[:user]
            end
            it 'adds 60 point with default' do
              post :create ,  params: {name: @user.name , sex: @user.sex , age: @user.age ,country: @user.country ,email: @user.email ,password: @user.password, password_confirmation: @user.password , confirmed_at: DateTime.now }
             expect(response).to render_template root_path
             expect(@user.points).to eq (60)
           end
         end
       end

我的registrations_controller.rb在下面。

       class Users::RegistrationsController < Devise::RegistrationsController
             def create
              super
              if resource.save
                resource.rewards.create(point: 60)
              end
             end
       end

它是自定义控制器,所以我的配置/路由.rb 在下面。

               Rails.application.routes.draw do
                devise_for :users, controllers: {
                  registrations: 'users/registrations' ,
                 }
               end

我在下面有错误。

            expected: 60
            got: 0

简而言之,我认为我无法创建用户,因为当我将"期望(@user.points).更改为eq (60)"到"期望(@user.reload.points).到eq(60)"时,我遇到了以下错误。

        Couldn't find User without an ID

为什么会出现错误?请帮助我。无论如何,用户模型文件如下。

     class User < ActiveRecord::Base
         devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :trackable, :validatable, :confirmable, :timeoutable, :omniauthable, :omniauth_providers => [:facebook]
          default_scope -> {order(created_at: :desc)}
          validates :name , presence: true , length: {maximum: 18}
          validates :sex , presence: true
          validates :age , presence: true
          validates :country , presence: true
          def points(force_reload = false)
           self.rewards(force_reload).sum(:point)
          end
        end

和我的应用程序控制器在下面(在文件中使用设计强参数)

         class ApplicationController < ActionController::Base
            protect_from_forgery with: :exception
            before_filter :configure_permitted_parameters, if: :devise_controller?
            def after_sign_in_path_for(resource)
              if (session[:previous_url] == user_path(resource) )
                    user_path(resource)
              else
                    session[:previous_url] || user_path(resource)
              end
            end

           protected
              def configure_permitted_parameters
                    devise_parameter_sanitizer.permit(:sign_up, keys: [:name,:age,:sex,:skill,:content, :picture , :country , :language1, :language2 ])
                    devise_parameter_sanitizer.permit(:account_update, keys: [:name,:age,:sex,:skill,:content, :picture , :country , :language1, :language2 ])
            end  
          end

我的测试.log如下。

        Processing by Users::RegistrationsController#create as HTML
        Parameters: {"params"=>{"email"=>"shiruba.hayatan1@docomo.ne.jp", "name"=>"Shiruba", "sex"=>"男性", "age"=>"10代", "country"=>"Japan", "language1"=>"Japanese", "language2"=>"Korea", "content"=>"heyheyheyeheyeheye", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "confirmed_at"=>"2017-01-04T02:33:47+00:00"}}
       [1m[35m (0.1ms)[0m  SAVEPOINT active_record_1
       [1m[36m (0.1ms)[0m  [1mROLLBACK TO SAVEPOINT active_record_1[0m
       Rendered devise/registrations/new.html.erb within layouts/application (0.3ms)
       Completed 200 OK in 937ms (Views: 13.5ms | ActiveRecord: 0.7ms)

我的工厂在下面。

       FactoryGirl.define do
        factory :user do
         sequence :email do |n|
         "shiruba#{n}@docomo.ne.jp"
         end
         name "Shiruba"
         sex "男性"
         age "10代"
         country 'Japan'
         content 'heyheyheyeheyeheye'
         password "shibaa"
         password_confirmation "shibaa"
         confirmed_at { DateTime.now } #ブロックに入れることでこれを実行したときのnowになる。
          end
       end

你应该用块来调用super:

class Users::RegistrationsController < Devise::RegistrationsController
  def create
    # almost all the devise controller actions 
    # yield the user being created or modified
    super do |resource|
      resource.rewards.new(point: 60)
    end
    # the user is saved as usual in the super class method
    # this also causes associated records to be saved if it is valid.
  end
end

此外,您完全滥用了FactoryGirl.build和变量@user.build创建一个模型实例并伪造持久性。所以在这一行中:

expect(@user.points).to eq (60)

只是期望您分配给规范中@user的假用户有 60 分。它不会告诉您控制器是否正常工作。

require 'rails_helper'
RSpec.describe Users::RegistrationsController, type: :controller do
  describe "POST #create" do
    # Using 'let' and not @ivars is preferred in rspec.  
    let(:valid_attributes) { FactoryGirl.attributes_for(:user, confirmed_at: Time.now) }
    it "creates a new user" do
      expect do
        post :create, params: valid_attributes
      end.to change(User, :count).by(+1)
    end
     it "gives the user 60 points for signing up" do
      post :create, params: valid_attributes
      expect(User.find_by_email(valid_attributes[:email]).points).to eq 60
    end
  end
end

最新更新