0

I implemented point system. User.point increases by 2 when he does login. My devise session controller is below.

 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 

and My spec/controllers/users_controller_spec.rb is below.

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 

and my model/user.rb is below.

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

When I did rspec command , I had this error.

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

I confirmed that @user.points increased by 2 in rails/console. Why do I have this error? Please tell me.

By looking at answers , I change it to below.

 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 

2 Answers 2

1

First, have you configured the routing since you use a custom controller (albeit that inherits from Devise Session controller)?

something like this, but in your case, it's sessions instead of registrations:

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

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

Second, since you basically use a custom controller, try hitting the controller the normal way rather than using the Devise test helper. Assuming you got the login_user method from the Devise documentation like below here:

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 

you have to understand that the login_user method DOES NOT make a request to the Users::SessionsController you created. This is why your callback after_action :add_point, only: [:create] is not triggered, hence no points were added to the logged_in user.

What I meant by hitting the rspec with proper request is calling like this:

post :create, params: { session_params } 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your comment! I changed spec file , and showed it in this question. but it doesn't work. I have the same error...
0

In most cases that will work:

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

Looks like @user instance is desynchronized with DB.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.