защищенный метод «отклонения» с использованием Rails 3 RC, Mongoid, Recaptcha и RSpec - PullRequest
4 голосов
/ 26 августа 2010

Пожалуйста, потерпите меня, так как я немного новичок в рельсах (особенно в рельсах 3), и я немного озадачен этим. По сути, я хочу протестировать свой CustomersController в моем приложении с использованием RSpec. Когда я выполняю свои спецификации, пытаясь выполнить публикацию в действии create в моем контроллере, я получаю эту ошибку, и я не уверен, почему:

1) CustomersController as guest should render new template when executing create action with invalid model
    Failure/Error: post :create, :customer => model
    protected method `reject' called for #<Customer:0x0000010611c400>
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/mongoid-2.0.0.beta.16/lib/mongoid/attributes.rb:23:in `method_missing'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/activemodel-3.0.0.rc/lib/active_model/mass_assignment_security/sanitizer.rb:6:in `sanitize'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/activemodel-3.0.0.rc/lib/active_model/mass_assignment_security.rb:153:in `sanitize_for_mass_assignment'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/mongoid-2.0.0.beta.16/lib/mongoid/attributes.rb:42:in `process'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/mongoid-2.0.0.beta.16/lib/mongoid/document.rb:104:in `initialize'
    # ./app/controllers/customers_controller.rb:11:in `new'
    # ./app/controllers/customers_controller.rb:11:in `create'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/action_controller/metal/implicit_render.rb:4:in `send_action'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/abstract_controller/base.rb:136:in `process_action'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/action_controller/metal/rendering.rb:11:in `process_action'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/abstract_controller/callbacks.rb:18:in `block in process_action'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb:429:in `_run__4199577925444808436__process_action__3619821760006806352__callbacks'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb:404:in `_run_process_action_callbacks'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb:93:in `run_callbacks'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/abstract_controller/callbacks.rb:17:in `process_action'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0.rc/lib/active_support/notifications.rb:52:in `block in instrument'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0.rc/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.0.rc/lib/active_support/notifications.rb:52:in `instrument'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/action_controller/metal/instrumentation.rb:29:in `process_action'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/action_controller/metal/rescue.rb:17:in `process_action'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/abstract_controller/base.rb:105:in `process'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/abstract_controller/rendering.rb:40:in `process'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/action_controller/metal/testing.rb:12:in `process_with_new_base_test'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/action_controller/test_case.rb:404:in `process'
    # /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.0.0.rc/lib/action_controller/test_case.rb:347:in `post'
    # ./spec/controllers/customers_controller_spec.rb:14:in `block (2 levels) in <top (required)>'

Теперь мне очень жаль, но вот много кода для подражания. Во-первых, это мои драгоценные камни.

mongoid (2.0.0.beta.16)
mongoid-rspec (1.2.0)
...
rspec (2.0.0.beta.19)
rspec-core (2.0.0.beta.19)
rspec-expectations (2.0.0.beta.19)
rspec-mocks (2.0.0.beta.19)
rspec-rails (2.0.0.beta.19)
...
rails (3.0.0.rc)
...
recaptcha (0.2.3)

Теперь мой CustomersController определен следующим образом:

class CustomersController < ApplicationController

  respond_to :html
  before_filter :authenticate_customer!, :except => [ :new, :create ]

  def new
    @customer = Customer.new
  end

  def create
    @customer = Customer.new(params[:customer])
    if verify_recaptcha(:model => @customer, :message => "Image verification failed.  Please try again.") && @customer.save 
      flash[:notice] = "Your account has been created successfully"
    end
    respond_with @customer
  end

  def show
  end
end

Вот моя модель клиента:

class Customer
  include Mongoid::Document
  devise :database_authenticatable, :recoverable, :rememberable,
    :trackable, :validatable

  field :first_name
  field :last_name
  field :email
  field :roles, :type => Array, :default => [ 'User' ]

  embeds_many :servers

  validates_presence_of :first_name
  validates_presence_of :last_name
  validates_presence_of :email
  validates_presence_of :roles

  validates_uniqueness_of :email

  attr_accessible :first_name, :last_name, :email,
                  :password, :password_confirmation

  def role?(role)
    return !!self.roles.include?(role.to_s.camelize)
  end

end

Наконец, вот моя спецификация:

describe CustomersController, "as guest" do
  include Devise::TestHelpers

  it "should render new template when executing new action" do
    get :new
    response.should render_template(:new)
  end

  it "should render new template when executing create action with invalid model" do
    model = Customer.new(:first_name => "Test", :last_name => "user")
    post :create, :customer => model
    response.should render_template(:new)
  end
end

1 Ответ

2 голосов
/ 02 сентября 2010

Что ж, получается, что мне приходилось передавать кортеж вместо реального объекта модели в каждом из моих тестов.Я переключился на использование factory_girl для создания объектов модели, а затем вызвал метод attributes_for для каждого объекта модели.Я передал этот результат в действие create, и все заработало как положено.

...