簡體   English   中英

RSpec測試PUT更新動作

[英]RSpec test PUT update action

我正在嘗試編寫一些RSpec測試來測試我的應用程序,但我偶然發現了一些我找不到任何解決方案的問題。 1)我正在嘗試測試更新操作。 這是我的代碼:

        it "email is a new one" do
            put :update, id: @user, user: FactoryGirl.attributes_for(:user, :email=>"a@b.c")
            @user.reload
            @user.email.should == "a@b.c"
            puts @user.email
        end

這是UsersController更新操作:

  def update
    @user = User.find(params[:id])
    respond_to do |format|
      if @user.update_attributes(params[:user])
        format.html { redirect_to edit_user_path(@user), :notice => "Your settings 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

這是錯誤:

 Failure/Error: @user.email.should == "a@b.c"
       expected: "a@b.c"
            got: "user16@example.com" (using ==)

很明顯,測試沒有改變用戶的電子郵件。 我從這里獲取了更新操作教程: http//everydayrails.com/2012/04/07/testing-series-rspec-controllers.html 哪里可以找到解決方案?

@user.update_attributes(params[:user])是否因驗證原因而失敗?

此外,您可以確保您的測試和控制器方法與同一個ruby對象進行交互。 這對我來說過去很困難。 我這樣做的方法是在類上存根find方法。

it "email is a new one" do
  User.stubs(:find).returns(@user)
  put :update, id: @user, user: FactoryGirl.attributes_for(:user, :email=>"a@b.c")
  @user.reload
  @user.email.should == "a@b.c"
  puts @user.email
end

這可以確保您在測試期間不僅討論相同的記錄,而且討論相同的對象。


最后,我認為你的測試對你來說非常重要。 您基本上是在測試update_attributes ,這是一項核心功能,已經過全面測試。 我將專注於測試控制器行為。 像這樣的東西:

let(:user) { FactoryGirl.create(:user) }

describe "PUT #update" do

  before(:each) {
    User.stubs(:find).returns(user)
  }

  it "should redirect to the user path on succesful save" do
    user.should_receive(:update_attributes).and_return true
    put :update, user, {}
    response.should redirect_to(edit_user_path(user))
  end

  it "should render the edit screen again with errors if the model doesn't save" do
    user.should_receive(:update_attributes).and_return false
    put :update, user, {}
    response.should render_template("edit")
  end
end

我認為put的論點是不正確的。

putgetdeletepost接受三個參數。 第一個是路徑,第二個是params,第三個是選項。

在你的代碼中你把兩個參數作為兩個參數,這是不正確的。

put :update, id: @user, user: FactoryGirl.attributes_for(:user, :email=>"a@b.c")

所以,改成它

put :update, {id: @user, user: FactoryGirl.attributes_for(:user, :email=>"a@b.c")}

可是等等! 您的代碼將通過上述更改工作,但您當前的代碼中存在安全漏洞。 確保您將添加權限檢查控制器代碼。 例如

return unauthorized unless @user == current_user || current_user.role == "admin"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM