我的“更新请求的用户”部分测试失败,我无法理解原因。
describe "PUT/PATCH #update_profile" do
context "with valid params" do
it "updates the requested user" do
user = create(:john_doe)
# Assuming there are no other users in the database, this
# specifies that the User created on the previous line
# receives the :update_attributes message with whatever params are
# submitted in the request.
User.any_instance.should_receive(:update_profile).with({identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id"=>user.identity.id}})
put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id"=>user.identity.id}}}
end
it "assigns the requested user as @user" do
user = create(:john_doe)
put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id"=>user.identity.id}} }
expect(assigns(:user)).to eq(user)
end
it "redirects to the user" do
user = create(:john_doe)
put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id"=>user.identity.id}}}
expect(response).to redirect_to foundry_users_url
end
end
其他2个部分(分配和重定向)传递正常,并且在浏览器中进行测试时,所有部分都按预期工作。
错误讯息为"RSpec::Mocks::MockExpectationError: Exactly one instance should have received the following message(s) but didn't: update_profile"
用户has_one :identity
和accepts_nested_attributes_for :identity
class Foundry::UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :edit_profile, :update_profile, :destroy]
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
format.html { redirect_to foundry_users_url, flash: {success: "User was successfully created."} }
format.json { render action: 'show', status: :created, location: @user }
else
format.html { render action: 'new' }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @user.update(user_params_for_update)
format.html { redirect_to foundry_users_url, notice: 'Credentials were successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
def update_profile
respond_to do |format|
if @user.update(user_params_for_update_profile)
format.html { redirect_to foundry_users_url, notice: 'Profile was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit_profile' }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
def user_params
# used only on creation
params.require(:user).permit(:email, identity_attributes: [:last_name, :first_name])
end
def user_params_for_update
# used only on 'regular' update action -- updates only credentials that are user's attributes
params.require(:user).permit(:email, :password, :password_confirmation)
end
def user_params_for_update_profile
# used only on update_profile action (later should have identity_attributes, addresses_attributes, and some others...)
params.require(:user).permit(identity_attributes: [:last_name, :first_name, :email_rescue, :dob, :bio, :gender, :id])
end
我想我在某个地方做某些事情,但我看不出在哪里以及为什么......
感谢您的帮助
答案 0 :(得分:1)
我有它工作!感谢@DNNX让我按照正确的方向指出问题与编写测试的方式一样,user.any_instance应该收到:update_profile而不是update。我把这里的传递规范放在这里..
describe "PUT/PATCH #update_profile" do
context "with valid params" do
it "updates the requested user" do
user = create(:john_doe)
User.any_instance.should_receive(:update_profile).with({"identity_attributes"=>{"last_name" => "BIDON", "first_name" => "Bidon", "dob" => "1970-07-15"}})
put :update_profile, {:id => user.to_param, :user => {:identity_attributes =>{last_name: 'BIDON', first_name: 'Bidon', dob: "1970-07-15"}}}
end
it "assigns the user as @user" do
user = create(:john_doe)
# Trigger the behavior that occurs when valid params are submitted
User.any_instance.stub(:update_profile).and_return(true)
put :update_profile, {:id => user.to_param, :user => { identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15"}}}
expect(assigns(:user)).to eq(user)
end
it "redirects to users list" do
user = create(:john_doe)
# Trigger the behavior that occurs when valid params are submitted
User.any_instance.stub(:update_profile).and_return(true)
put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15"}}}
expect(response).to redirect_to foundry_users_url
end
end
context "with invalid params" do
it "assigns the user as @user" do
user = create(:john_doe)
# Trigger the behavior that occurs when invalid params are submitted
User.any_instance.stub(:update_profile).and_return(false)
put :update_profile, {:id => user.to_param, :user => { identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id" => user.identity.id}}}
expect(assigns(:user)).to eq(user)
end
it "re-renders the 'edit_profile' template" do
user = create(:john_doe)
# Trigger the behavior that occurs when invalid params are submitted
User.any_instance.stub(:update_profile).and_return(false)
put :update_profile, {:id => user.to_param, :user => {identity_attributes:{"last_name" => "Bidon", "first_name" => "Bidon", "dob" => "1970-07-15", "id" => user.identity.id}}}
expect(response).to render_template :edit_profile
end
end
end
在我的问题中发布的其余代码仍然相同..现在,所有测试都是绿色的
编辑在DNNX的评论中写道,我忘了提到控制器本身的基本修改,我把它放在这里: def update_profile
respond_to do |format|
if @user.update_profile(user_params_for_update_profile) // changed to call update_profile instead of update !
// rest of code still the same
干杯
答案 1 :(得分:0)
您的控制器不会在update_profile
的任何实例上调用User
。它调用User#update
。试试这个:
User.
any_instance.
should_receive(:update).
with(identity_attributes: {
"last_name" => "Bidon",
"first_name" => "Bidon",
"dob" => "1970-07-15",
"id" => user.identity.id})
如果上面的代码不起作用,或者这个:
User.any_instance.should_receive(:update)