2017-01-03 19 views
0

私はポイントシステムを実装しています。ユーザーが作成すると、ユーザーにはいくつかの点があります。 私のregistrations_controller_spec.rbは以下の通りです。登録のRspecエラーdevysの処置

  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 

とMy registrations_controller.rbは以下のとおりです。

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

これはカスタムコントローラなので、私のconfig/routes.rbは以下の通りです。

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

私は以下のエラーがあります。要するに

  expected: 60 
      got: 0 

は、私は「期待(@ user.points).TO EQ(60)」「を期待する(@userを変更したときに以下のエラーが発生しましたので、私は、ユーザーを作成することができなかったと思います。 reload.points).to 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 

と私のApplicationControllerには、私のtest.logは以下の通りです

  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 

(用途はファイル内の強いパラメータを考案)以下です。

 Processing by Users::RegistrationsController#create as HTML 
     Parameters: {"params"=>{"email"=>"[email protected]", "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 
+0

'expect(@ user.points).to eq(60)'の代わりに 'expect(User.last.points).to eq(60)'を試すことができますか?あなたの '@ user'はまだ保存されていないので、' IDなしでユーザーを見つけることができませんでした '(ただし、 '@ user'に基づいて値を設定した別のユーザーを保存しました) – amree

答えて

1

あなたは代わりにブロックでスーパーを呼び出す必要があります:

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 
+0

ありがとうあなたの丁寧なコメントのために!私は参照してください。しかし、それは動作しません...私は '1で変更された期待数#と同じエラーが発生しましたが、0で変更されました。私はそれが強力なパラメータから、(私は私の質問でapplication_controller.rbを追加した)原因だと思ったが、間違ったコードを持っていないと思った。ごめんなさい。 –

+0

これは、レコードがコントローラに保存されていないことを意味します。 'logs/test.log'をチェックして何が失敗しているのかを確認し、ファクトリが有効な属性を生成していることを確認してください。 – max

+0

私は工場が有効な属性を生成すると思う。私はlogs/test.logをチェックし、そのファイルはテストが成功したことを示しています。私の質問にファイルを追加します。これは非常に不思議なことです...私は多くの質問でとても申し訳ありません。 –