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.