3

この質問の冗長性について事前にお詫び申し上げます。辛抱していただければ、実際には非常に単純であることがわかると思います...私のRailsドメインの知識が限られているため、説明するのが難しいだけです。

8 月 6 日付の ActionController コミットでこのコメントが与えられた場合:

 === Builtin HTTP verb semantics

 Rails default renderer holds semantics for each HTTP verb. Depending on the
 content type, verb and the resource status, it will behave differently.

 Using Rails default renderer, a POST request for creating an object could
 be written as:

   def create   
     @user = User.new(params[:user])    
     flash[:notice] = 'User was successfully created.' if @user.save
     respond_with(@user)
       end

 Which is exactly the same as:

   def create
     @user = User.new(params[:user])

     respond_to do |format|
       if @user.save
         flash[:notice] = 'User was successfully created.'
         format.html { redirect_to(@user) }
         format.xml { render :xml => @user, :status => :created, :location => @user }
       else
         format.html { render :action => "new" }
         format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
       end
     end
   end

 The same happens for PUT and DELETE requests.

使用する非常に基本的なコントローラーを変更しましたrespond_withparamsRailsの自動生成されたテストが更新および作成メソッドに空を渡そうとすると、2つの仕様が失敗することを除いて、すべてが正常に機能しているようです。この動作は単純な if save/else で修正できますが、この「新しい」機能を理解しようとしています。デフォルトの仕様は時代遅れの方法で書かれている可能性があると思います。

コミットコメントから: " Since the request is a POST, respond_with will check wether @people resource have errors or not. If it has errors, it will render the error object with unprocessable entity status (422)."

したがって、POST の下の最後のテスト/仕様 (以下) までスクロールすると、「処理不能なエンティティ ステータス (422)」をテストして合格し、すべてが桃色になるように書き直すことができますか?

私のコントローラー:

class ClownsController < ApplicationController
  respond_to :html, :json

  def index
    respond_with(@clowns = Clown.all)
  end

  def show
    respond_with(@clown = Clown.find(params[:id]))
  end

  def new
    respond_with(@clown = Clown.new)
  end

  def edit
    respond_with(@clown = Clown.find(params[:id]))
  end

  def create
     @clown = Clown.new(params[:clown])
     flash[:notice] = 'Clown was successfully created.' if @clown.save
     respond_with(@clown) 
  end

  # Replacing def create above with this won't Fail the spec ##
  #
  # def create
  #    @clown = Clown.new(params[:clown])
  #    respond_with(@clown) do |format|
  #      if @clown.save
  #        flash[:notice] = 'Clown was successfully created.'
  #        format.html { redirect_to @clown }
  #      else
  #        format.html { render :action => :new }
  #      end
  #    end
  # end


  def update
    @clown = Clown.find(params[:id])
    flash[:notice] = 'Clown has been updated.' if @clown.update_attributes(params[:clown])
    respond_with(@clown)
  end

  def destroy
    @clown = Clown.find(params[:id])
    flash[:notice] = 'Successfully deleted clown.' if @clown.destroy
    respond_with(@clown)
  end
end

仕様のテスト:

$ rspec spec/
.......F....F..............

Failures:

  1) ClownsController POST create with invalid params re-renders the 'new' template
     Failure/Error: response.should render_template("new")
     expecting <"new"> but rendering with <"">.
     Expected block to return true value.
     # (eval):2:in `assert_block'
     # ./spec/controllers/clowns_controller_spec.rb:69:in `block (4 levels) in <top (required)>'

  2) ClownsController PUT update with invalid params re-renders the 'edit' template
     Failure/Error: response.should render_template("edit")
     expecting <"edit"> but rendering with <"">.
     Expected block to return true value.
     # (eval):2:in `assert_block'
     # ./spec/controllers/clowns_controller_spec.rb:107:in `block (4 levels) in <top (required)>'

これは clowns_controller_spec.rb の一部です:

require 'spec_helper'

describe ClownsController do

  def mock_clown(stubs={})
    (@mock_clown ||= mock_model(Clown).as_null_object).tap do |clown|
      clown.stub(stubs) unless stubs.empty?
    end
  end

...

  describe "POST create" do

    describe "with invalid params" do    
      it "re-renders the 'new' template" do
        Clown.stub(:new) { mock_clown(:save => false) }
        post :create, :clown => {}
        response.should render_template("new")
      end
    end
4

1 に答える 1

2

次のように Clown クラスをモックしてみてください

Clown.stub(:new) { mock_clown(:errors => {:any => 'error'}) }

このようにして、respond_with メソッドはモデルの保存が失敗したことを認識し、新しいテンプレートをレンダリングします。

于 2012-03-07T17:43:28.777 に答える