簡體   English   中英

如何為簡單的PUT更新編寫RSpec測試?

[英]How to write an RSpec test for a simple PUT update?

我正在努力鞏固我對rails和BDD工作流程的理解,所以我想通過創建其中一個迷你博客來開始,但是使用rspec。 現在我有一個ArticlesController和Article模型,以及相關的rspec文件。 文章非常簡單,只有標題:字符串和內容:文本,而ArticlesController是RESTful - 雖然我手寫了MCV for Article,但它基本上和我用腳手架創建它一樣。

但是,當我在rspec中為PUT更新編寫測試時,我真的不知道我在做什么。 我正在使用Factory Girl來創建文章對象,到目前為止我的代碼看起來像:

#factories.rb
FactoryGirl.define do
  factory :article do
  title "a title"
  content "hello world"
end

#articles_controller_spec.rb
before(:each) do
  @article = Factory(:article)
end

describe "PUT 'update/:id'" do
  it "allows an article to be updated" do
    @attr = { :title => "new title", :content => "new content" }
    put :update, :id => @article.id, :article => @attr
    response.should be_successful
  end
end

但是我一直在:

Failures:
1) ArticlesController PUT 'update/:id' allows an article to be updated
   Failure/Error: response.should be_successful
     expected successful? to return true, got false

我究竟做錯了什么? 我使用正確的工具嗎? 當我運行我的測試服務器時,New,Edit,Destroy所有工作正如我所期望的那樣,所以我猜這是我對RSpec理解的問題。 如果我錯了,請告訴我 - 謝謝!

你忘記了.reload你的@article ,在update操作上,你的回復最有可能執行重定向,所以

RSpec 2:

describe "PUT update/:id" do
  let(:attr) do 
    { :title => 'new title', :content => 'new content' }
  end

  before(:each) do
    put :update, :id => @article.id, :article => attr
    @article.reload
  end

  it { response.should redirect_to(@article) }
  it { @article.title.should eql attr[:title] }
  it { @article.content.should eql attr[:content] }
end

Rspec 3:

describe "PUT update/:id" do
  let(:attr) do 
    { :title => 'new title', :content => 'new content' }
  end

  before(:each) do
    put :update, :id => @article.id, :article => attr
    @article.reload
  end

  it { expect(response).to redirect_to(@article) }
  it { expect(@article.title).to eql attr[:title] }
  it { expect(@article.content).to eql attr[:content] }
end

當你正在做一個PUT :update記住,你是編輯現有的模式,你需要在調用put 只需傳遞您的@article並更新屬性,如下所示。

describe "PUT 'update/:id'" do
  it "allows an article to be updated" do
    put :update, :id => @article.id, :article => @article.attributes = { :title => "new title", :content => "new content" }
    response.should be_successful
  end
end
FactoryGirl.define :article do
  title "a title"
  content "hello world"
end

before(:each) do
  @article = Factory(:article)
end

it "should re-render edit template on failed update" do
  @attr = { :title => "", :content => "new content" }
  put :update, :id => @article.id, :article => @attr

  flash[:notice].should be_nil
  response.should render_template('edit')
end

it "should redirect to index with a notice on successful update" do
  @attr = { :title => "new title", :content => "new content" }
  put :update, :id => @article.id, :article => @attr

  assigns[:article].should_not be_new_record
  flash[:notice].should_not be_nil
  response.should redirect_to(:action => 'index')
end

我喜歡測試更新方法的方法是確保updated_at時間比以前更大。 執行此操作時,您可以更改整個實例變量的內容,並仍然檢查是否所有內容都已更新。 例如:

describe "PUT 'update/:id'" do
  it "allows an article to be updated" do
    prev_updated_at = @article.updated_at
    @attr = { :title => "new title", :content => "new content" }
    put :update, :id => @article.id, :article => @attr
    @article.reload
    @article.updated_at.should != prev_updated_at 
  end
end

暫無
暫無

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

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