3

Извините заранее за многословие этого вопроса. Если вы несете со мной, я думаю, вы обнаружите, что это на самом деле довольно просто ... мне просто трудно объяснить, учитывая мои ограниченные знания домена Rails.Работа с и тестирование Rails ActionController's response_with

Учитывая этот комментарий в an ActionController commit dated Aug 6:

=== 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_with. Кажется, что все работает нормально, за исключением того, что 2 specs терпят неудачу, когда Rails автоматически сгенерированные тесты пытаются пройти пустой params для обновления & методов создания. Я могу исправить это поведение простым, если 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 (ниже) я мог бы переписывание, что таким образом, что он проверяет на «статус unprocessable объекта (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 
+0

Пересмотр этой проблемы ... и до сих пор не знаю, что происходит ... так что просто пропустил пробные тесты ... очевидно, не идеально. – Meltemi 2011-02-14 20:42:26

ответ

2

Попробуйте насмешливый свой класс клоун с следующей

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

Таким образом, метод response_with будет знать, что сбой модели не удался и отобразит новый шаблон.

Смежные вопросы