web-dev-qa-db-ja.com

単純なPUT更新のRSpecテストを作成する方法は?

RailsとBDDワークフローの理解を固めようとしているので、これらのミニブログの1つを作成することから始めましたが、rspecを使用します。現在、ArticlesControllerとアーティクルモデル、および関連するrspecファイル。アーティクルは非常にシンプルで、title:stringとcontent:textのみを持ち、ArticlesControllerはRESTfulです。それ。

しかし、PUT更新のためにrspecでテストを作成することになると、私が何をしているか本当にわかりません。 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を実行すると、期待どおりにすべての作業が破棄されるため、これはRSpecの理解に問題があると推測しています。私が間違っているかどうか教えてください-ありがとう!

32
oort

.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
56

PUT :updateputで呼び出す必要がある既存のモデルを編集していることを思い出してください。 @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
7
nmott
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
1
Sandip Ransing

更新メソッドをテストする方法は、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
0
David Hahn