A bit stuck here being new to ruby and rspec
Im trying to spec out a rails controller and using machinist to
generate a model
so in my spec i have
it "should create new client" do
// creates me a hash of generated values using Foregey
client = Client.plan
// specify that I should be creating a new client with the hash
values from client
Client.should_receive(:new).with(client)
//post to the server
post ''create'' , :client => client
end
in my controller
def create
client = Client.new(params[:client])
end
now this is failing with
Spec::Mocks::MockExpectationError: received :new with
unexpected arguments
expected: ({:title=>"Mr",
:firstname=>"Ernest",
:lastname=>"Burke",
:email=>"rgarrett-zgEXW82lJqCZuzBka8ofvg@public.gmane.org"})
got: ({"title"=>"Mr",
"lastname"=>"Burke",
"firstname"=>"Ernest",
"email"=>"rgarrett-zgEXW82lJqCZuzBka8ofvg@public.gmane.org"})
is there a way to specify to use symbols instead of the strings as
keys, as I dont want to be doing
:client => { "title" => client.title , ............ }
as the client model may change over time
Cheers
On Tue, Feb 2, 2010 at 04:24, Stephen Smithstone <ssmithstone at me.com> wrote:> A bit stuck here being new to ruby and rspecWelcome. I hope you like the experience. Good news: we''ve seen what you''ve done a thousand times and so it''s quite easy to explain.> it "should create new client" do > ??? // creates me a hash of generated values using Foregey > ??? client = Client.plan > ??? // specify that I should be creating a new client with the hash values > from client > ??? Client.should_receive(:new).with(client) > ??? //post to the server > ??? post ''create'' , :client => client > end > > in my controller > > def create > ??? client = Client.new(params[:client]) > end > > now this is failing with > > Spec::Mocks::MockExpectationError: <Client(id: integer, created_at: > datetime, updated_at: datetime, title: string, lastname: string, firstname: > string, email: string) (class)> received :new with unexpected arguments > ? expected: ({:title=>"Mr", :firstname=>"Ernest", :lastname=>"Burke", > :email=>"rgarrett at blogtag.info"}) > ?????? got: ({"title"=>"Mr", "lastname"=>"Burke", "firstname"=>"Ernest", > "email"=>"rgarrett at blogtag.info"}) > > is there a way to specify to use symbols instead of the strings as keys, as > I dont want to be doing > > :client => { "title" => client.title , ............ } > > as the client model may change over timeTry Client.should_receive(:new).with(client.attributes), because the #attributes method turns a model into a Hash of symbol to value. It uses string keys instead of symbol keys, but that shouldn''t hurt you. Good luck. -- J. B. (Joe) Rainsberger :: http://www.jbrains.ca :: http://blog.thecodewhisperer.com Diaspar Software Services :: http://www.diasparsoftware.com Author, JUnit Recipes 2005 Gordon Pask Award for contribution to Agile practice :: Agile 2010: Learn. Practice. Explore.
cheers for the response , seem that attributes is missing from hash on my
system
all i did was the blueprint with a standard hash
client = { :title => "Mr }
client.attributes
NoMethodError: undefined method `attributes'' for
{:title=>"Mr"}:Hash
is attributes added on by rails ?
if so my setup must be wrong
On 2 February 2010 12:07, J. B. Rainsberger <jbrainsberger at gmail.com>
wrote:
> On Tue, Feb 2, 2010 at 04:24, Stephen Smithstone <ssmithstone at
me.com>
> wrote:
>
> > A bit stuck here being new to ruby and rspec
>
> Welcome. I hope you like the experience. Good news: we''ve seen
what
> you''ve done a thousand times and so it''s quite easy to
explain.
>
> > it "should create new client" do
> > // creates me a hash of generated values using Foregey
> > client = Client.plan
> > // specify that I should be creating a new client with the hash
> values
> > from client
> > Client.should_receive(:new).with(client)
> > //post to the server
> > post ''create'' , :client => client
> > end
> >
> > in my controller
> >
> > def create
> > client = Client.new(params[:client])
> > end
> >
> > now this is failing with
> >
> > Spec::Mocks::MockExpectationError: <Client(id: integer, created_at:
> > datetime, updated_at: datetime, title: string, lastname: string,
> firstname:
> > string, email: string) (class)> received :new with unexpected
arguments
> > expected: ({:title=>"Mr",
:firstname=>"Ernest", :lastname=>"Burke",
> > :email=>"rgarrett at blogtag.info"})
> > got: ({"title"=>"Mr",
"lastname"=>"Burke",
"firstname"=>"Ernest",
> > "email"=>"rgarrett at blogtag.info"})
> >
> > is there a way to specify to use symbols instead of the strings as
keys,
> as
> > I dont want to be doing
> >
> > :client => { "title" => client.title , ............ }
> >
> > as the client model may change over time
>
> Try Client.should_receive(:new).with(client.attributes), because the
> #attributes method turns a model into a Hash of symbol to value. It
> uses string keys instead of symbol keys, but that shouldn''t hurt
you.
>
> Good luck.
> --
> J. B. (Joe) Rainsberger :: http://www.jbrains.ca ::
> http://blog.thecodewhisperer.com
> Diaspar Software Services :: http://www.diasparsoftware.com
> Author, JUnit Recipes
> 2005 Gordon Pask Award for contribution to Agile practice :: Agile
> 2010: Learn. Practice. Explore.
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://rubyforge.org/pipermail/rspec-users/attachments/20100202/7ef1237d/attachment.html>
seems the blueprint is not inheriting from active record base so no #attributes on the class, have to look for another solution or pass in some parameters my self On 2 February 2010 12:26, Stephen Smithstone <stephen.smithstone at gmail.com>wrote:> cheers for the response , seem that attributes is missing from hash on my > system > > all i did was the blueprint with a standard hash > > client = { :title => "Mr } > > client.attributes > > NoMethodError: undefined method `attributes'' for {:title=>"Mr"}:Hash > > is attributes added on by rails ? > > if so my setup must be wrong > > > On 2 February 2010 12:07, J. B. Rainsberger <jbrainsberger at gmail.com>wrote: > >> On Tue, Feb 2, 2010 at 04:24, Stephen Smithstone <ssmithstone at me.com> >> wrote: >> >> > A bit stuck here being new to ruby and rspec >> >> Welcome. I hope you like the experience. Good news: we''ve seen what >> you''ve done a thousand times and so it''s quite easy to explain. >> >> > it "should create new client" do >> > // creates me a hash of generated values using Foregey >> > client = Client.plan >> > // specify that I should be creating a new client with the hash >> values >> > from client >> > Client.should_receive(:new).with(client) >> > //post to the server >> > post ''create'' , :client => client >> > end >> > >> > in my controller >> > >> > def create >> > client = Client.new(params[:client]) >> > end >> > >> > now this is failing with >> > >> > Spec::Mocks::MockExpectationError: <Client(id: integer, created_at: >> > datetime, updated_at: datetime, title: string, lastname: string, >> firstname: >> > string, email: string) (class)> received :new with unexpected arguments >> > expected: ({:title=>"Mr", :firstname=>"Ernest", :lastname=>"Burke", >> > :email=>"rgarrett at blogtag.info"}) >> > got: ({"title"=>"Mr", "lastname"=>"Burke", "firstname"=>"Ernest", >> > "email"=>"rgarrett at blogtag.info"}) >> > >> > is there a way to specify to use symbols instead of the strings as keys, >> as >> > I dont want to be doing >> > >> > :client => { "title" => client.title , ............ } >> > >> > as the client model may change over time >> >> Try Client.should_receive(:new).with(client.attributes), because the >> #attributes method turns a model into a Hash of symbol to value. It >> uses string keys instead of symbol keys, but that shouldn''t hurt you. >> >> Good luck. >> -- >> J. B. (Joe) Rainsberger :: http://www.jbrains.ca :: >> http://blog.thecodewhisperer.com >> Diaspar Software Services :: http://www.diasparsoftware.com >> Author, JUnit Recipes >> 2005 Gordon Pask Award for contribution to Agile practice :: Agile >> 2010: Learn. Practice. Explore. >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20100202/c9b0b197/attachment-0001.html>
The problem is that you''re passing a hash with symbols as keys, and
rails takes the params and converts it to a HashWithIndifferentAccess,
which actually stores the keys as strings.
One thing you might try to solve your problem is do this:
it "should create new client" do
client = Client.plan.with_indifferent_access
Client.should_receive(:new).with(client)
post ''create'' , :client => client
end
I guess that will probably solve it.
On an unrelated note?and here''s to opening a huge can of worms :)?I
usually dislike stubbing/mocking to do these simple tests. I tend to
like testing more the behavior of my controllers, so for a valid
create, I would write this test:
it "adds a new client" do
lambda { post :create, :client => Client.plan }.should
change(Client, :count).by(1)
end
Since this doesn''t rely on the implementation (calling
Client.new(params) ? which might change to
current_user.clients.new(params), and maybe some business logic is
added along the way and it turns into current_user.add_client(params)
at some point), it tells me that the action, provided valid
parameters, is working, and at the same time will resist a
refactoring.
(This is considering your action is a "standard" create action for a
rails controller)
But again, this is *my* usual approach, there are good reasons both in
favor of not mocking and in favor of mocking the behavior of your
models. I just like the ones in favor of not mocking a bit more :)
Cheers
On Tue, Feb 2, 2010 at 10:26 AM, Stephen Smithstone
<stephen.smithstone at gmail.com> wrote:> cheers for the response , seem that attributes is missing from hash on my
> system
>
> all i did was the blueprint with a standard hash
>
> client = { :title => "Mr }
>
> client.attributes
>
> NoMethodError: undefined method `attributes'' for
{:title=>"Mr"}:Hash
>
> is attributes added on by rails ?
>
> if so my setup must be wrong
>
> On 2 February 2010 12:07, J. B. Rainsberger <jbrainsberger at
gmail.com> wrote:
>>
>> On Tue, Feb 2, 2010 at 04:24, Stephen Smithstone <ssmithstone at
me.com>
>> wrote:
>>
>> > A bit stuck here being new to ruby and rspec
>>
>> Welcome. I hope you like the experience. Good news: we''ve seen
what
>> you''ve done a thousand times and so it''s quite easy
to explain.
>>
>> > it "should create new client" do
>> > ??? // creates me a hash of generated values using Foregey
>> > ??? client = Client.plan
>> > ??? // specify that I should be creating a new client with the
hash
>> > values
>> > from client
>> > ??? Client.should_receive(:new).with(client)
>> > ??? //post to the server
>> > ??? post ''create'' , :client => client
>> > end
>> >
>> > in my controller
>> >
>> > def create
>> > ??? client = Client.new(params[:client])
>> > end
>> >
>> > now this is failing with
>> >
>> > Spec::Mocks::MockExpectationError: <Client(id: integer,
created_at:
>> > datetime, updated_at: datetime, title: string, lastname: string,
>> > firstname:
>> > string, email: string) (class)> received :new with unexpected
arguments
>> > ? expected: ({:title=>"Mr",
:firstname=>"Ernest", :lastname=>"Burke",
>> > :email=>"rgarrett at blogtag.info"})
>> > ?????? got: ({"title"=>"Mr",
"lastname"=>"Burke",
"firstname"=>"Ernest",
>> > "email"=>"rgarrett at blogtag.info"})
>> >
>> > is there a way to specify to use symbols instead of the strings as
keys,
>> > as
>> > I dont want to be doing
>> >
>> > :client => { "title" => client.title ,
............ }
>> >
>> > as the client model may change over time
>>
>> Try Client.should_receive(:new).with(client.attributes), because the
>> #attributes method turns a model into a Hash of symbol to value. It
>> uses string keys instead of symbol keys, but that shouldn''t
hurt you.
>>
>> Good luck.
>> --
>> J. B. (Joe) Rainsberger :: http://www.jbrains.ca ::
>> http://blog.thecodewhisperer.com
>> Diaspar Software Services :: http://www.diasparsoftware.com
>> Author, JUnit Recipes
>> 2005 Gordon Pask Award for contribution to Agile practice :: Agile
>> 2010: Learn. Practice. Explore.
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
>
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
On Tue, Feb 2, 2010 at 10:54 AM, Stephen Smithstone <stephen.smithstone at gmail.com> wrote:> seems the blueprint is not inheriting from active record base so no > #attributes on the class, have to look for another solution or pass in some > parameters my selfModel#plan will just return a hash of attributes, using your blueprint. If you want an instance of the model, you can use Model#make, or Model#make_unsaved. (This is assuming you''re using Machinist, given the api you''re using)> On 2 February 2010 12:26, Stephen Smithstone <stephen.smithstone at gmail.com> > wrote: >> >> cheers for the response , seem that attributes is missing from hash on my >> system >> >> all i did was the blueprint with a standard hash >> >> client = { :title => "Mr } >> >> client.attributes >> >> NoMethodError: undefined method `attributes'' for {:title=>"Mr"}:Hash >> >> is attributes added on by rails ? >> >> if so my setup must be wrong >> >> On 2 February 2010 12:07, J. B. Rainsberger <jbrainsberger at gmail.com> >> wrote: >>> >>> On Tue, Feb 2, 2010 at 04:24, Stephen Smithstone <ssmithstone at me.com> >>> wrote: >>> >>> > A bit stuck here being new to ruby and rspec >>> >>> Welcome. I hope you like the experience. Good news: we''ve seen what >>> you''ve done a thousand times and so it''s quite easy to explain. >>> >>> > it "should create new client" do >>> > ??? // creates me a hash of generated values using Foregey >>> > ??? client = Client.plan >>> > ??? // specify that I should be creating a new client with the hash >>> > values >>> > from client >>> > ??? Client.should_receive(:new).with(client) >>> > ??? //post to the server >>> > ??? post ''create'' , :client => client >>> > end >>> > >>> > in my controller >>> > >>> > def create >>> > ??? client = Client.new(params[:client]) >>> > end >>> > >>> > now this is failing with >>> > >>> > Spec::Mocks::MockExpectationError: <Client(id: integer, created_at: >>> > datetime, updated_at: datetime, title: string, lastname: string, >>> > firstname: >>> > string, email: string) (class)> received :new with unexpected arguments >>> > ? expected: ({:title=>"Mr", :firstname=>"Ernest", :lastname=>"Burke", >>> > :email=>"rgarrett at blogtag.info"}) >>> > ?????? got: ({"title"=>"Mr", "lastname"=>"Burke", >>> > "firstname"=>"Ernest", >>> > "email"=>"rgarrett at blogtag.info"}) >>> > >>> > is there a way to specify to use symbols instead of the strings as >>> > keys, as >>> > I dont want to be doing >>> > >>> > :client => { "title" => client.title , ............ } >>> > >>> > as the client model may change over time >>> >>> Try Client.should_receive(:new).with(client.attributes), because the >>> #attributes method turns a model into a Hash of symbol to value. It >>> uses string keys instead of symbol keys, but that shouldn''t hurt you. >>> >>> Good luck. >>> -- >>> J. B. (Joe) Rainsberger :: http://www.jbrains.ca :: >>> http://blog.thecodewhisperer.com >>> Diaspar Software Services :: http://www.diasparsoftware.com >>> Author, JUnit Recipes >>> 2005 Gordon Pask Award for contribution to Agile practice :: Agile >>> 2010: Learn. Practice. Explore. >>> _______________________________________________ >>> rspec-users mailing list >>> rspec-users at rubyforge.org >>> http://rubyforge.org/mailman/listinfo/rspec-users >> > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
very interesting thought there :-) , thrown a
spanner in my works now
On 02/02/2010 13:19, Nicolás Sanguinetti wrote:
The problem is that you''re passing a hash with symbols as keys, and
rails takes the params and converts it to a HashWithIndifferentAccess,
which actually stores the keys as strings.
One thing you might try to solve your problem is do this:
it "should create new client" do
client = Client.plan.with_indifferent_access
Client.should_receive(:new).with(client)
post ''create'' , :client => client
end
I guess that will probably solve it.
On an unrelated note—and here''s to opening a huge can of worms :)—I
usually dislike stubbing/mocking to do these simple tests. I tend to
like testing more the behavior of my controllers, so for a valid
create, I would write this test:
it "adds a new client" do
lambda { post :create, :client => Client.plan }.should
change(Client, :count).by(1)
end
Since this doesn''t rely on the implementation (calling
Client.new(params) — which might change to
current_user.clients.new(params), and maybe some business logic is
added along the way and it turns into current_user.add_client(params)
at some point), it tells me that the action, provided valid
parameters, is working, and at the same time will resist a
refactoring.
(This is considering your action is a "standard" create action for a
rails controller)
But again, this is *my* usual approach, there are good reasons both in
favor of not mocking and in favor of mocking the behavior of your
models. I just like the ones in favor of not mocking a bit more :)
Cheers
On Tue, Feb 2, 2010 at 10:26 AM, Stephen Smithstone
wrote:
cheers for the response , seem that attributes is missing from hash on my
system
all i did was the blueprint with a standard hash
client = { :title => "Mr }
client.attributes
NoMethodError: undefined method `attributes'' for
{:title=>"Mr"}:Hash
is attributes added on by rails ?
if so my setup must be wrong
On 2 February 2010 12:07, J. B. Rainsberger wrote:
On Tue, Feb 2, 2010 at 04:24, Stephen Smithstone
wrote:
A bit stuck here being new to ruby and rspec
Welcome. I hope you like the experience. Good news: we''ve seen what
you''ve done a thousand times and so it''s quite easy to
explain.
it "should create new client" do
// creates me a hash of generated values using Foregey
client = Client.plan
// specify that I should be creating a new client with the hash
values
from client
Client.should_receive(:new).with(client)
//post to the server
post ''create'' , :client => client
end
in my controller
def create
client = Client.new(params[:client])
end
now this is failing with
Spec::Mocks::MockExpectationError: received :new with unexpected arguments
expected: ({:title=>"Mr",
:firstname=>"Ernest", :lastname=>"Burke",
:email=>"rgarrett-zgEXW82lJqCZuzBka8ofvg@public.gmane.org"})
got: ({"title"=>"Mr",
"lastname"=>"Burke",
"firstname"=>"Ernest",
"email"=>"rgarrett-zgEXW82lJqCZuzBka8ofvg@public.gmane.org"})
is there a way to specify to use symbols instead of the strings as keys,
as
I dont want to be doing
:client => { "title" => client.title , ............ }
as the client model may change over time
Try Client.should_receive(:new).with(client.attributes), because the
#attributes method turns a model into a Hash of symbol to value. It
uses string keys instead of symbol keys, but that shouldn''t hurt you.
Good luck.
--
J. B. (Joe) Rainsberger :: http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Diaspar Software Services :: http://www.diasparsoftware.com
Author, JUnit Recipes
2005 Gordon Pask Award for contribution to Agile practice :: Agile
2010: Learn. Practice. Explore.
_______________________________________________
rspec-users mailing list
rspec-users-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org
http://rubyforge.org/mailman/listinfo/rspec-users
On Tue, Feb 2, 2010 at 07:26, Stephen Smithstone <stephen.smithstone at gmail.com> wrote:> cheers for the response , seem that attributes is missing from hash on my > systemYou''ll find #attributes on ActiveRecord::Base, and not Hash. Try this: it "should create new client" do // creates me a hash of generated values using Foregey client = Client.plan // specify that I should be creating a new client with the hash values from client Client.should_receive(:new).with(client.attributes) //post to the server post ''create'' , :client => client end -- J. B. (Joe) Rainsberger :: http://www.jbrains.ca :: http://blog.thecodewhisperer.com Diaspar Software Services :: http://www.diasparsoftware.com Author, JUnit Recipes 2005 Gordon Pask Award for contribution to Agile practice :: Agile 2010: Learn. Practice. Explore.
On Tue, Feb 2, 2010 at 09:18, J. B. Rainsberger <jbrainsberger at gmail.com> wrote:> On Tue, Feb 2, 2010 at 07:26, Stephen Smithstone > <stephen.smithstone at gmail.com> wrote: > >> cheers for the response , seem that attributes is missing from hash on my >> system > > You''ll find #attributes on ActiveRecord::Base, and not Hash.I responded too soon. Ignore my response. I don''t know Machinist, and so I can''t help you. -- J. B. (Joe) Rainsberger :: http://www.jbrains.ca :: http://blog.thecodewhisperer.com Diaspar Software Services :: http://www.diasparsoftware.com Author, JUnit Recipes 2005 Gordon Pask Award for contribution to Agile practice :: Agile 2010: Learn. Practice. Explore.