0

我的测试中的“更新请求的用户”部分失败了,我不明白为什么。

 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"

编辑:我在这里添加用户控制器(我只保留代码的相关部分:创建操作更新操作(供参考)和 update_profile 操作(导致规范失败)。请记住,只有这个规范失败,所有其他工作预料之中,问题出在我写测试的方式上。

用户has_one :identityaccepts_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

我想我在某个地方做错了什么,但我看不出在哪里以及为什么......

谢谢你的帮助

4

2 回答 2

1

我有它的工作!感谢@DNNX,他让我朝着正确的方向前进,正如预期的那样,问题出在我编写测试的方式上,user.any_instance 应该收到 :update_profile 而不是更新。我在这里放了传递规范以供参考。

  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

干杯

于 2013-07-10T16:44:48.373 回答
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)
于 2013-07-10T15:23:42.703 回答