我实现积分系统。当用户创建时,用户有一些点。我的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