-
-
Save annacruz/4957484 to your computer and use it in GitHub Desktop.
it "instantiates record with params" do | |
# require 'pry'; binding.pry | |
url = mock_model(Url) | |
post :create, :original_url => "http://example.org" | |
Url.should_receive(:new).with({"original_url" => "http://example.org"}).and_return(url) | |
end |
class Url
include Mongoid::Document
field :original_url
field :visits, type: Integer, default: 0
field :uid
validates :original_url, :format => {with: %r[\Ahttps?://]i}, :presence => true
validates :visits, presence: true
validates :uid, uniqueness: true
after_create :uid
def self.find_by_uid(uid)
find_by_id(Uid.decode(uid))
end
def uid
self.uid = id.hash.abs.to_s(36)
end
end
- UrlsController POST :create with valid data instantiates record with params
Failure/Error: post :create, :original_url => "http://example.org"
<Url (class)> received :new with unexpected arguments
expected: ({"original_url"=>"http://example.org"})
got: ({"original_url"=>"http://example.org", "controller"=>"urls", "action"=>"create"})./app/controllers/urls_controller.rb:8:in `create'
./spec/controllers/url_controller_spec.rb:10:in`block (4 levels) in <top (required)>'
Failure/Error: post :create, :url => { :original_url => "http://example.org" }
<Url (class)> received :new with unexpected arguments
expected: ({"original_url"=>"http://example.org"})
got: (nil)
Vamos lá confere ai:
spec
it "instantiates record with params" do
# require 'pry'; binding.pry
url = mock_model(Url)
post :create, :url => { :original_url => "http://example.org" }
Url.should_receive(:new).with({"original_url" => "http://example.org"}).and_return(url)
end
controller
class UrlsController < ActionController::Base
#...
def create
@url = Url.new(params[:url])
render :nothing => true
end
end
Explicando a spec:
Quando você estiver na sua spec de controller usando algum método do rspec que simula o verbo http da action, o primeiro parâmetro do método será a action e o segundo um hash que será passado para dentro da variável params, isso para o rspec se comportar como se os dados estivessem vindo de um formulário, ex:
post :create, :objeto => { :atributo_um => "valor um", :atributo_dois => "valor dois" }
put :update, :objeto => { :atributo_um => "valor um", :atributo_dois => "valor dois" }
# isso manda para o controller um params(que é um hash) com várias chaves,
# se você printar o params no controller você verá algo como
puts params[:objeto] # => { :atributo_um => "valor um", :atributo_dois => "valor dois" }
# se a chave passada fosse :url como no seu caso os atributos seriam acessados através de ```params[:url]``` como aconteceu.
Isso acontece, pois como falei o segundo parametro é um hash. O fato de se passar um :objeto
como chave do hash é para simular o comportamento do objeto no formulário.
Por exemplo no seu caso o seu campo original_url
seria montado algo como
<input type="text" name="url[original_url]" id="url_original_url" value=""/>
...que no controller seria acessado através de params[:url]
onde url é a chave do hash
class Url
include Mongoid::Document
field :original_url
field :visits, type: Integer, default: 0
field :uid
validates :original_url, :format => {with: %r[\Ahttps?://]i}, :presence => true
validates :visits, presence: true
validates :uid, uniqueness: true
after_create :uid
def self.find_by_uid(uid)
find_by_id(Uid.decode(uid))
end
def uid
self.uid = id.hash.abs.to_s(36)
end
end