Let''s say you''re using the restful_authentication plugin. You have a model called articles. On the index action of the articlescontroller you simply want to spec out that it''ll scope the results to the ownership of the current_user. It should NOT include any articles other than the articles that user owns. How would you properly spec this out? Thanks for the help! -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071203/1d33f697/attachment.html
Let''s say you''re using the restful_authentication plugin. You have a model called articles. On the index action of the articlescontroller you simply want to spec out that it''ll scope the results to the ownership of the current_user. It should NOT include any articles other than the articles that user owns. How would you properly spec this out? Thanks for the help! -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071203/362a4bab/attachment.html
Typically, I''d write a method in your user model that returns the user''s articles: class User do def find_articles_for_user Article.find(:all, :conditions => [''userid = ?'', id) end end Then you''d use a mock in your controller spec, and make sure you test that your method is being called. On the other hand, the user model should be tested directly against the db. HTH, Stefan 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>:> > Let''s say you''re using the restful_authentication plugin. > You have a model called articles. On the index action of the > articlescontroller you simply want to spec out that it''ll scope the results > to the ownership of the current_user. > > It should NOT include any articles other than the articles that user owns. > > How would you properly spec this out? > > Thanks for the help! > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-- Bekk Open Source http://boss.bekk.no -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071203/ca3fda82/attachment.html
yuck, that seems kind of nasty, no? user.articles is already scoped... There has to be a different solution! On Dec 3, 2007 2:07 AM, Stefan Magnus Landr? <stefan.landro at gmail.com> wrote:> Typically, I''d write a method in your user model that returns the user''s > articles: > > class User do > > def find_articles_for_user > Article.find(:all, :conditions => [''userid = ?'', id) > end > > end > > Then you''d use a mock in your controller spec, and make sure you test that > your method is being called. > > On the other hand, the user model should be tested directly against the > db. > > HTH, > > Stefan > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > Let''s say you''re using the restful_authentication plugin. > > You have a model called articles. On the index action of the > > articlescontroller you simply want to spec out that it''ll scope the results > > to the ownership of the current_user. > > > > It should NOT include any articles other than the articles that user > > owns. > > > > How would you properly spec this out? > > > > Thanks for the help! > > > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > -- > Bekk Open Source > http://boss.bekk.no > _______________________________________________ > 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/20071203/78dbb660/attachment-0001.html
On 3.12.2007, at 11.57, Fischer, Daniel wrote:> Let''s say you''re using the restful_authentication plugin. > > You have a model called articles. On the index action of the > articlescontroller you simply want to spec out that it''ll scope the > results to the ownership of the current_user. > > It should NOT include any articles other than the articles that user > owns.Given that you have user has_many :articles You want to use current_user.articles (or current_user.articles.find(*additional options*)). In the spec, you want to make sure that the articles are scoped through the correct user: before(:each) do @user = mock_model(User) User.stub!(:find).and_return(@user) # to make sure current_user is the mock model @articles = [mock_model(Article)] end it "should find articles for the current user" do @user.should_receive(:articles).and_return(@articles) get :index end It is then the responsibility of the articles association to scope the results. In the controller specs you just trust that it works. -- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi
Assuming that there is a call like this in your controller @articles = current_user.articles One way to do this is to stub out the controller.current_user to return a mock object of the current_user Then put an expectation on the current user that it''s articles method gets called. (return a mocked collection of articles) Then check that @articles is set to the returned mocked collection of articles from current_user.articles phew... Ok So one way you might write this could be (This is untested...) it "should scope the articles to the currrent_user" do user = mock_model(User) articles = [mock_model(Article)] controller.stub!(:current_user).and_return(user) user.should_receive(:articles).and_return(articles) get :index assigns[:articles].should == articles end Like I said though, that''s not tested itself. If that''s not exactly right... it''s along the right track of an option that can work. HTH Daniel On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? <stefan.landro at gmail.com> wrote:> Typically, I''d write a method in your user model that returns the user''s > articles: > > class User do > > def find_articles_for_user > Article.find(:all, :conditions => [''userid = ?'', id) > end > > end > > Then you''d use a mock in your controller spec, and make sure you test that > your method is being called. > > On the other hand, the user model should be tested directly against the > db. > > HTH, > > Stefan > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > Let''s say you''re using the restful_authentication plugin. > > You have a model called articles. On the index action of the > > articlescontroller you simply want to spec out that it''ll scope the results > > to the ownership of the current_user. > > > > It should NOT include any articles other than the articles that user > > owns. > > > > How would you properly spec this out? > > > > Thanks for the help! > > > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > -- > Bekk Open Source > http://boss.bekk.no > _______________________________________________ > 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/20071203/cffdf875/attachment.html
Hi Daniel, You''re trying to do too much in the controller. It''s not the controller''s responsibility to ensure that the user is capable of returning its own article without including anyone else''s - that''s the user''s (or the Article model''s, perhaps) responsibility. Your controller should be thin and simple, delegating all business logic onto the model objects. See this article: http://www.pragprog.com/ articles/tell-dont-ask Once thinned down like this, speccing the controller becomes trivial - just mock the current_user method and ensure that it receives a call to "available_articles" or whatever the method name is. Then, spec that method in the User model. At that point, don''t mock anything you don''t have to, and test the behaviour of the User model (e.g. "it should not return anyone else''s article within its available articles" or something like that). Hope this helps, Daniel On 3 Dec 2007, at 10:33 3 Dec 2007, Fischer, Daniel wrote:> yuck, that seems kind of nasty, no? > > user.articles is already scoped... > > There has to be a different solution! > > On Dec 3, 2007 2:07 AM, Stefan Magnus Landr? > <stefan.landro at gmail.com> wrote: > Typically, I''d write a method in your user model that returns the > user''s articles: > > class User do > > def find_articles_for_user > Article.find(:all, :conditions => [''userid = ?'', id) > end > > end > > Then you''d use a mock in your controller spec, and make sure you > test that your method is being called. > > On the other hand, the user model should be tested directly against > the db. > > HTH, > > Stefan > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > Let''s say you''re using the restful_authentication plugin. > > You have a model called articles. On the index action of the > articlescontroller you simply want to spec out that it''ll scope the > results to the ownership of the current_user. > > It should NOT include any articles other than the articles that > user owns. > > How would you properly spec this out? > > Thanks for the help! > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > > > > -- > Bekk Open Source > http://boss.bekk.no > _______________________________________________ > 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-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071203/8555842d/attachment.html
Well, if articles is already scoped, you just say: user.should_receive(''articles'').and_return(some_articles) To make sure your articles method is scoped, write a model test that hits the database, and verify that only the user''s articles are returned. As Daniel Tenner says, you should try to keep your controllers as thin as possible. In addition you should try to keep your tests as fast as possible - and you typically do that by not hitting the DB. Stefan 2007/12/3, Fischer, Daniel <me at danielfischer.com>:> > yuck, that seems kind of nasty, no? > user.articles is already scoped... > > There has to be a different solution! > > On Dec 3, 2007 2:07 AM, Stefan Magnus Landr? <stefan.landro at gmail.com> > wrote: > > > Typically, I''d write a method in your user model that returns the user''s > > articles: > > > > class User do > > > > def find_articles_for_user > > Article.find(:all, :conditions => [''userid = ?'', id) > > end > > > > end > > > > Then you''d use a mock in your controller spec, and make sure you test > > that your method is being called. > > > > On the other hand, the user model should be tested directly against the > > db. > > > > HTH, > > > > Stefan > > > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > > > Let''s say you''re using the restful_authentication plugin. > > > You have a model called articles. On the index action of the > > > articlescontroller you simply want to spec out that it''ll scope the results > > > to the ownership of the current_user. > > > > > > It should NOT include any articles other than the articles that user > > > owns. > > > > > > How would you properly spec this out? > > > > > > Thanks for the help! > > > > > > _______________________________________________ > > > rspec-users mailing list > > > rspec-users at rubyforge.org > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > > > > -- > > Bekk Open Source > > http://boss.bekk.no > > _______________________________________________ > > 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 >-- Bekk Open Source http://boss.bekk.no -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071203/9cb5dd5a/attachment-0001.html
Hey cool, thanks for the help guys. One problem though, when I take this approach I can''t decouple the specs anymore. They all "User_xxx receive unexpected message :articles". It seems silly to include all behaviors in one spec, or put that expectation in each test. Is there a way around this? Thanks for all the help, Daniel Fischer http://www.danielfischer.com On Dec 3, 2007 2:44 AM, Daniel N <has.sox at gmail.com> wrote:> Assuming that there is a call like this in your controller > @articles = current_user.articles > > One way to do this is to stub out the controller.current_user to return a > mock object of the current_user > > Then put an expectation on the current user that it''s articles method gets > called. (return a mocked collection of articles) > > Then check that @articles is set to the returned mocked collection of > articles from current_user.articles > > phew... > > Ok So one way you might write this could be (This is untested...) > > it "should scope the articles to the currrent_user" do > > user = mock_model(User) > articles = [mock_model(Article)] > > controller.stub!(:current_user).and_return(user) > user.should_receive (:articles).and_return(articles) > > get :index > > assigns[:articles].should == articles > > end > > Like I said though, that''s not tested itself. If that''s not exactly > right... it''s along the right track of an option that can work. > > HTH > Daniel > > On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? <stefan.landro at gmail.com> > wrote: > > > Typically, I''d write a method in your user model that returns the user''s > > articles: > > > > class User do > > > > def find_articles_for_user > > Article.find(:all, :conditions => [''userid = ?'', id) > > end > > > > end > > > > Then you''d use a mock in your controller spec, and make sure you test > > that your method is being called. > > > > On the other hand, the user model should be tested directly against the > > db. > > > > HTH, > > > > Stefan > > > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > > > Let''s say you''re using the restful_authentication plugin. > > > You have a model called articles. On the index action of the > > > articlescontroller you simply want to spec out that it''ll scope the results > > > to the ownership of the current_user. > > > > > > It should NOT include any articles other than the articles that user > > > owns. > > > > > > How would you properly spec this out? > > > > > > Thanks for the help! > > > > > > _______________________________________________ > > > rspec-users mailing list > > > rspec-users at rubyforge.org > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > > > > -- > > Bekk Open Source > > http://boss.bekk.no > > _______________________________________________ > > 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 >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071203/06371128/attachment.html
I also have another problem, when I am trying to do the similar strategy for XML based speccing it fails on saying nil.to_xml Arg.. And all it is, is the following => (with a before_filter on login required) but still, it''s just current_user. def show @writing = current_user.writings.find(params[:id]) respond_to do |format| format.html format.xml { render :xml => @writing.to_xml } end end http://pastie.textmate.org/private/99vq9ipqb6u8cu5bfirlaa here is the pastie. On Dec 3, 2007 8:26 PM, Fischer, Daniel <me at danielfischer.com> wrote:> Hey cool, thanks for the help guys. One problem though, when I take this > approach I can''t decouple the specs anymore. They all "User_xxx receive > unexpected message :articles". It seems silly to include all behaviors in > one spec, or put that expectation in each test. Is there a way around this? > Thanks for all the help, > Daniel Fischer > http://www.danielfischer.com > > > On Dec 3, 2007 2:44 AM, Daniel N < has.sox at gmail.com> wrote: > > > Assuming that there is a call like this in your controller > > @articles = current_user.articles > > > > One way to do this is to stub out the controller.current_user to return > > a mock object of the current_user > > > > Then put an expectation on the current user that it''s articles method > > gets called. (return a mocked collection of articles) > > > > Then check that @articles is set to the returned mocked collection of > > articles from current_user.articles > > > > phew... > > > > Ok So one way you might write this could be (This is untested...) > > > > it "should scope the articles to the currrent_user" do > > > > user = mock_model(User) > > articles = [mock_model(Article)] > > > > controller.stub!(:current_user).and_return(user) > > user.should_receive (:articles).and_return(articles) > > > > get :index > > > > assigns[:articles].should == articles > > > > end > > > > Like I said though, that''s not tested itself. If that''s not exactly > > right... it''s along the right track of an option that can work. > > > > HTH > > Daniel > > > > On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? <stefan.landro at gmail.com> > > wrote: > > > > > Typically, I''d write a method in your user model that returns the > > > user''s articles: > > > > > > class User do > > > > > > def find_articles_for_user > > > Article.find(:all, :conditions => [''userid = ?'', id) > > > end > > > > > > end > > > > > > Then you''d use a mock in your controller spec, and make sure you test > > > that your method is being called. > > > > > > On the other hand, the user model should be tested directly against > > > the db. > > > > > > HTH, > > > > > > Stefan > > > > > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > > > > > Let''s say you''re using the restful_authentication plugin. > > > > You have a model called articles. On the index action of the > > > > articlescontroller you simply want to spec out that it''ll scope the results > > > > to the ownership of the current_user. > > > > > > > > It should NOT include any articles other than the articles that user > > > > owns. > > > > > > > > How would you properly spec this out? > > > > > > > > Thanks for the help! > > > > > > > > _______________________________________________ > > > > rspec-users mailing list > > > > rspec-users at rubyforge.org > > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > > > > > > > > > -- > > > Bekk Open Source > > > http://boss.bekk.no > > > _______________________________________________ > > > 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 > > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071203/85856ef7/attachment.html
On Dec 3, 2007 10:26 PM, Fischer, Daniel <me at danielfischer.com> wrote:> Hey cool, thanks for the help guys. One problem though, when I take this > approach I can''t decouple the specs anymore. They all "User_xxx receive > unexpected message :articles". It seems silly to include all behaviors in > one spec, or put that expectation in each test. Is there a way around this?Sure. Create a method somewhere that generates a baseline stub for you. module UserControllerSpecHelper def create_stub_user mock_model(User, :articles => []) end end describe UserController, "..." do include UserControllerSpecHelper before(:each) do @user = create_stub_user end end If there are other methods you need to stub on all instances of user, do it in the helper. Then you can use message expectations (mocks) where you need them to describe specific behaviour. HTH, David> > Thanks for all the help, > Daniel Fischer > http://www.danielfischer.com > > > > On Dec 3, 2007 2:44 AM, Daniel N < has.sox at gmail.com> wrote: > > Assuming that there is a call like this in your controller > > > > > > @articles = current_user.articles > > > > > > One way to do this is to stub out the controller.current_user to return a > mock object of the current_user > > > > > > Then put an expectation on the current user that it''s articles method gets > called. (return a mocked collection of articles) > > > > > > Then check that @articles is set to the returned mocked collection of > articles from current_user.articles > > > > > > phew... > > > > > > Ok So one way you might write this could be (This is untested...) > > > > > > it "should scope the articles to the currrent_user" do > > > > > > user = mock_model(User) > > articles = [mock_model(Article)] > > > > > > controller.stub!(:current_user).and_return(user) > > > > user.should_receive (:articles).and_return(articles) > > > > get :index > > > > assigns[:articles].should == articles > > > > > > end > > > > > > Like I said though, that''s not tested itself. If that''s not exactly > right... it''s along the right track of an option that can work. > > > > > > HTH > > Daniel > > > > > > > > On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? <stefan.landro at gmail.com> > wrote: > > > > > > > > > > > Typically, I''d write a method in your user model that returns the user''s > articles: > > > > > > class User do > > > > > > def find_articles_for_user > > > Article.find(:all, :conditions => [''userid = ?'', id) > > > end > > > > > > end > > > > > > Then you''d use a mock in your controller spec, and make sure you test > that your method is being called. > > > > > > On the other hand, the user model should be tested directly against the > db. > > > > > > HTH, > > > > > > Stefan > > > > > > > > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > > > > > > > > > > > > > Let''s say you''re using the restful_authentication plugin. > > > > > > > > > > > > You have a model called articles. On the index action of the > articlescontroller you simply want to spec out that it''ll scope the results > to the ownership of the current_user. > > > > > > > > > > > > It should NOT include any articles other than the articles that user > owns. > > > > > > > > > > > > How would you properly spec this out? > > > > > > > > > > > > Thanks for the help! > > > > _______________________________________________ > > > > rspec-users mailing list > > > > rspec-users at rubyforge.org > > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > > > > > > > > > -- > > > Bekk Open Source > > > http://boss.bekk.no > > > _______________________________________________ > > > 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 > > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Alright, thanks, I''m getting more progress in this. As soon as I figure this out I won''t have too many problems.. hopefully. Anyone know what "undefined method `call'' for "1":String" means? I''m trying to do this: http://pastie.textmate.org/private/17jjjmbave0ph2mkcgp6w On Dec 3, 2007 9:33 PM, David Chelimsky <dchelimsky at gmail.com> wrote:> On Dec 3, 2007 10:26 PM, Fischer, Daniel <me at danielfischer.com> wrote: > > Hey cool, thanks for the help guys. One problem though, when I take this > > approach I can''t decouple the specs anymore. They all "User_xxx receive > > unexpected message :articles". It seems silly to include all behaviors > in > > one spec, or put that expectation in each test. Is there a way around > this? > > Sure. Create a method somewhere that generates a baseline stub for you. > > module UserControllerSpecHelper > def create_stub_user > mock_model(User, :articles => []) > end > end > > describe UserController, "..." do > include UserControllerSpecHelper > before(:each) do > @user = create_stub_user > end > end > > If there are other methods you need to stub on all instances of user, > do it in the helper. Then you can use message expectations (mocks) > where you need them to describe specific behaviour. > > HTH, > David > > > > > Thanks for all the help, > > Daniel Fischer > > http://www.danielfischer.com > > > > > > > > On Dec 3, 2007 2:44 AM, Daniel N < has.sox at gmail.com> wrote: > > > Assuming that there is a call like this in your controller > > > > > > > > > @articles = current_user.articles > > > > > > > > > One way to do this is to stub out the controller.current_user to > return a > > mock object of the current_user > > > > > > > > > Then put an expectation on the current user that it''s articles method > gets > > called. (return a mocked collection of articles) > > > > > > > > > Then check that @articles is set to the returned mocked collection of > > articles from current_user.articles > > > > > > > > > phew... > > > > > > > > > Ok So one way you might write this could be (This is untested...) > > > > > > > > > it "should scope the articles to the currrent_user" do > > > > > > > > > user = mock_model(User) > > > articles = [mock_model(Article)] > > > > > > > > > controller.stub!(:current_user).and_return(user) > > > > > > user.should_receive (:articles).and_return(articles) > > > > > > get :index > > > > > > assigns[:articles].should == articles > > > > > > > > > end > > > > > > > > > Like I said though, that''s not tested itself. If that''s not exactly > > right... it''s along the right track of an option that can work. > > > > > > > > > HTH > > > Daniel > > > > > > > > > > > > On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? <stefan.landro at gmail.com> > > wrote: > > > > > > > > > > > > > > > > Typically, I''d write a method in your user model that returns the > user''s > > articles: > > > > > > > > class User do > > > > > > > > def find_articles_for_user > > > > Article.find(:all, :conditions => [''userid = ?'', id) > > > > end > > > > > > > > end > > > > > > > > Then you''d use a mock in your controller spec, and make sure you > test > > that your method is being called. > > > > > > > > On the other hand, the user model should be tested directly against > the > > db. > > > > > > > > HTH, > > > > > > > > Stefan > > > > > > > > > > > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > > > > > > > > > > > > > > > > > Let''s say you''re using the restful_authentication plugin. > > > > > > > > > > > > > > > You have a model called articles. On the index action of the > > articlescontroller you simply want to spec out that it''ll scope the > results > > to the ownership of the current_user. > > > > > > > > > > > > > > > It should NOT include any articles other than the articles that > user > > owns. > > > > > > > > > > > > > > > How would you properly spec this out? > > > > > > > > > > > > > > > Thanks for the help! > > > > > _______________________________________________ > > > > > rspec-users mailing list > > > > > rspec-users at rubyforge.org > > > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > > > > > > > > > > > > > > -- > > > > Bekk Open Source > > > > http://boss.bekk.no > > > > _______________________________________________ > > > > 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 > > > > > > > > > _______________________________________________ > > 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 >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071203/ced91e2a/attachment.html
Sorry for so many messages, I hope I don''t get in trouble for this. Maybe IRC would be better if there was a RSpec one. Anyway, the previous problem was solved with the following http://pastie.textmate.org/private/m6qqfd7tzeanw2yar8rua The problem was caused by : @user = mock_model(User, :writings => [] ) I''m not sure if that is a bug or what, but that''s what caused it. It''d also say "no block given" if I put something there other than a "mock". On Dec 3, 2007 10:33 PM, Fischer, Daniel <me at danielfischer.com> wrote:> Alright, thanks, I''m getting more progress in this. As soon as I figure > this out I won''t have too many problems.. hopefully. > Anyone know what "undefined method `call'' for "1":String" means? > > I''m trying to do this: > > http://pastie.textmate.org/private/17jjjmbave0ph2mkcgp6w > > > On Dec 3, 2007 9:33 PM, David Chelimsky <dchelimsky at gmail.com> wrote: > > > On Dec 3, 2007 10:26 PM, Fischer, Daniel <me at danielfischer.com> wrote: > > > Hey cool, thanks for the help guys. One problem though, when I take > > this > > > approach I can''t decouple the specs anymore. They all "User_xxx > > receive > > > unexpected message :articles". It seems silly to include all behaviors > > in > > > one spec, or put that expectation in each test. Is there a way around > > this? > > > > Sure. Create a method somewhere that generates a baseline stub for you. > > > > module UserControllerSpecHelper > > def create_stub_user > > mock_model(User, :articles => []) > > end > > end > > > > describe UserController, "..." do > > include UserControllerSpecHelper > > before(:each) do > > @user = create_stub_user > > end > > end > > > > If there are other methods you need to stub on all instances of user, > > do it in the helper. Then you can use message expectations (mocks) > > where you need them to describe specific behaviour. > > > > HTH, > > David > > > > > > > > Thanks for all the help, > > > Daniel Fischer > > > http://www.danielfischer.com > > > > > > > > > > > > On Dec 3, 2007 2:44 AM, Daniel N < has.sox at gmail.com> wrote: > > > > Assuming that there is a call like this in your controller > > > > > > > > > > > > @articles = current_user.articles > > > > > > > > > > > > One way to do this is to stub out the controller.current_user to > > return a > > > mock object of the current_user > > > > > > > > > > > > Then put an expectation on the current user that it''s articles > > method gets > > > called. (return a mocked collection of articles) > > > > > > > > > > > > Then check that @articles is set to the returned mocked collection > > of > > > articles from current_user.articles > > > > > > > > > > > > phew... > > > > > > > > > > > > Ok So one way you might write this could be (This is untested...) > > > > > > > > > > > > it "should scope the articles to the currrent_user" do > > > > > > > > > > > > user = mock_model(User) > > > > articles = [mock_model(Article)] > > > > > > > > > > > > controller.stub!(:current_user).and_return(user) > > > > > > > > user.should_receive (:articles).and_return(articles) > > > > > > > > get :index > > > > > > > > assigns[:articles].should == articles > > > > > > > > > > > > end > > > > > > > > > > > > Like I said though, that''s not tested itself. If that''s not exactly > > > right... it''s along the right track of an option that can work. > > > > > > > > > > > > HTH > > > > Daniel > > > > > > > > > > > > > > > > On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? <stefan.landro at gmail.com > > > > > > wrote: > > > > > > > > > > > > > > > > > > > > > Typically, I''d write a method in your user model that returns the > > user''s > > > articles: > > > > > > > > > > class User do > > > > > > > > > > def find_articles_for_user > > > > > Article.find(:all, :conditions => [''userid = ?'', id) > > > > > end > > > > > > > > > > end > > > > > > > > > > Then you''d use a mock in your controller spec, and make sure you > > test > > > that your method is being called. > > > > > > > > > > On the other hand, the user model should be tested directly > > against the > > > db. > > > > > > > > > > HTH, > > > > > > > > > > Stefan > > > > > > > > > > > > > > > 2007/12/3, Fischer, Daniel < daniel at helpmebuyacar.org>: > > > > > > > > > > > > > > > > > > > > > > > > Let''s say you''re using the restful_authentication plugin. > > > > > > > > > > > > > > > > > > You have a model called articles. On the index action of the > > > articlescontroller you simply want to spec out that it''ll scope the > > results > > > to the ownership of the current_user. > > > > > > > > > > > > > > > > > > It should NOT include any articles other than the articles that > > user > > > owns. > > > > > > > > > > > > > > > > > > How would you properly spec this out? > > > > > > > > > > > > > > > > > > Thanks for the help! > > > > > > _______________________________________________ > > > > > > rspec-users mailing list > > > > > > rspec-users at rubyforge.org > > > > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > > > > > > > > > > > > > > > > > > > -- > > > > > Bekk Open Source > > > > > http://boss.bekk.no > > > > > _______________________________________________ > > > > > 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 > > > > > > > > > > > > > _______________________________________________ > > > 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 > > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071203/83b97e7b/attachment-0001.html
On 4.12.2007, at 8.40, Fischer, Daniel wrote:> Sorry for so many messages, I hope I don''t get in trouble for this. > Maybe IRC would be better if there was a RSpec one.#rspec @freenode //jarkko -- Jarkko Laine http://jlaine.net http://dotherightthing.com http://www.railsecommerce.com http://odesign.fi
btw, to answer the same question for member actions (such as show), you can stub or assert the association proxy class @article = current_user.articles.find(params[:id]) then, it "should find article scoped by current_user" do article = mock_model(Article) current_user.should_receive(:articles).and_return(Article) Article.should_receive(:find).and_return(article) get :show, :id => article.id end this will ensure that your controller is not calling Article.find unscoped linoj On Dec 3, 2007, at 5:44 AM, Daniel N wrote:> Assuming that there is a call like this in your controller > > @articles = current_user.articles > > One way to do this is to stub out the controller.current_user to > return a mock object of the current_user > > Then put an expectation on the current user that it''s articles > method gets called. (return a mocked collection of articles) > > Then check that @articles is set to the returned mocked collection > of articles from current_user.articles > > phew... > > Ok So one way you might write this could be (This is untested...) > > it "should scope the articles to the currrent_user" do > > user = mock_model(User) > articles = [mock_model(Article)] > > controller.stub!(:current_user).and_return(user) > user.should_receive (:articles).and_return(articles) > > get :index > > assigns[:articles].should == articles > > end > > Like I said though, that''s not tested itself. If that''s not > exactly right... it''s along the right track of an option that can > work. > > HTH > Daniel > > On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? > <stefan.landro at gmail.com> wrote: > Typically, I''d write a method in your user model that returns the > user''s articles: > > class User do > > def find_articles_for_user > Article.find(:all, :conditions => [''userid = ?'', id) > end > > end > > Then you''d use a mock in your controller spec, and make sure you > test that your method is being called. > > On the other hand, the user model should be tested directly against > the db. > > HTH, > > Stefan > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > Let''s say you''re using the restful_authentication plugin. > > You have a model called articles. On the index action of the > articlescontroller you simply want to spec out that it''ll scope the > results to the ownership of the current_user. > > It should NOT include any articles other than the articles that > user owns. > > How would you properly spec this out? > > Thanks for the help! > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > > > > -- > Bekk Open Source > http://boss.bekk.no > _______________________________________________ > 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-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071216/157a15e3/attachment.html
On Dec 16, 2007 11:03 AM, Jonathan Linowes <jonathan at parkerhill.com> wrote:> > btw, to answer the same question for member actions (such as show), you can > stub or assert the association proxy class > > @article = current_user.articles.find(params[:id]) > > then, > > it "should find article scoped by current_user" do > article = mock_model(Article) > current_user.should_receive(:articles).and_return(Article) > Article.should_receive(:find).and_return(article) > get :show, :id => article.id > end > > this will ensure that your controller is not calling Article.find unscopedI tend to take this one more step. I''m a bit of a demeter zealot, and I''m also usually writing the examples from the code first. So I''d do something like: it "should find the current users articles" do article = mock_model(Article) current_user.should_receive(:find_article).with("1").and_return(Article) get :show, :id => "1" end This would lead me to add a find_article method to User: describe User do it "should find it''s own articles" do user = User.new user.articles.should_receive(:find).with("1") user.find_article("1) end end This has two benefits: - each example is simpler and focuses on one object and how it behaves - I can change the relationship between a User and it''s Articles without changing the controller code. FWIW, David> > linoj > > > > > On Dec 3, 2007, at 5:44 AM, Daniel N wrote: > Assuming that there is a call like this in your controller > > @articles = current_user.articles > > One way to do this is to stub out the controller.current_user to return a > mock object of the current_user > > Then put an expectation on the current user that it''s articles method gets > called. (return a mocked collection of articles) > > Then check that @articles is set to the returned mocked collection of > articles from current_user.articles > > phew... > > Ok So one way you might write this could be (This is untested...) > > it "should scope the articles to the currrent_user" do > > user = mock_model(User) > articles = [mock_model(Article)] > > controller.stub!(:current_user).and_return(user) > user.should_receive (:articles).and_return(articles) > > get :index > > assigns[:articles].should == articles > > end > > > Like I said though, that''s not tested itself. If that''s not exactly > right... it''s along the right track of an option that can work. > > HTH > Daniel > > On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? <stefan.landro at gmail.com> > wrote: > > Typically, I''d write a method in your user model that returns the user''s > articles: > > > > class User do > > > > def find_articles_for_user > > Article.find(:all, :conditions => [''userid = ?'', id) > > end > > > > end > > > > Then you''d use a mock in your controller spec, and make sure you test that > your method is being called. > > > > On the other hand, the user model should be tested directly against the > db. > > > > HTH, > > > > Stefan > > > > > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > > > > > > > > > Let''s say you''re using the restful_authentication plugin. > > > > > > > > > You have a model called articles. On the index action of the > articlescontroller you simply want to spec out that it''ll scope the results > to the ownership of the current_user. > > > > > > > > > It should NOT include any articles other than the articles that user > owns. > > > > > > > > > How would you properly spec this out? > > > > > > > > > Thanks for the help! > > > _______________________________________________ > > > rspec-users mailing list > > > rspec-users at rubyforge.org > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > > > > -- > > Bekk Open Source > > http://boss.bekk.no > > _______________________________________________ > > 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 > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On Dec 17, 2007 8:43 AM, David Chelimsky <dchelimsky at gmail.com> wrote:> On Dec 16, 2007 11:03 AM, Jonathan Linowes <jonathan at parkerhill.com> > wrote: > > > > btw, to answer the same question for member actions (such as show), you > can > > stub or assert the association proxy class > > > > @article = current_user.articles.find(params[:id]) > > > > then, > > > > it "should find article scoped by current_user" do > > article = mock_model(Article) > > current_user.should_receive(:articles).and_return(Article) > > Article.should_receive(:find).and_return(article) > > get :show, :id => article.id > > end > > > > this will ensure that your controller is not calling Article.findunscoped > > I tend to take this one more step. I''m a bit of a demeter zealot, and > I''m also usually writing the examples from the code first. So I''d do > something like: > > it "should find the current users articles" do > article = mock_model(Article) > current_user.should_receive(:find_article).with("1").and_return(Article) > get :show, :id => "1" > endWhere is current_user defined here? I''ve always stubbed current_user on the controller object. How are you doing this one?> > > This would lead me to add a find_article method to User: > > describe User do > it "should find it''s own articles" do > user = User.new > user.articles.should_receive(:find).with("1") > user.find_article("1) > end > end > > This has two benefits: > - each example is simpler and focuses on one object and how it behaves > - I can change the relationship between a User and it''s Articles > without changing the controller code. > > FWIW, > David > > > > > > linoj > > > > > > > > > > On Dec 3, 2007, at 5:44 AM, Daniel N wrote: > > Assuming that there is a call like this in your controller > > > > @articles = current_user.articles > > > > One way to do this is to stub out the controller.current_user to return > a > > mock object of the current_user > > > > Then put an expectation on the current user that it''s articles method > gets > > called. (return a mocked collection of articles) > > > > Then check that @articles is set to the returned mocked collection of > > articles from current_user.articles > > > > phew... > > > > Ok So one way you might write this could be (This is untested...) > > > > it "should scope the articles to the currrent_user" do > > > > user = mock_model(User) > > articles = [mock_model(Article)] > > > > controller.stub!(:current_user).and_return(user) > > user.should_receive (:articles).and_return(articles) > > > > get :index > > > > assigns[:articles].should == articles > > > > end > > > > > > Like I said though, that''s not tested itself. If that''s not exactly > > right... it''s along the right track of an option that can work. > > > > HTH > > Daniel > > > > On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? <stefan.landro at gmail.com> > > wrote: > > > Typically, I''d write a method in your user model that returns the > user''s > > articles: > > > > > > class User do > > > > > > def find_articles_for_user > > > Article.find(:all, :conditions => [''userid = ?'', id) > > > end > > > > > > end > > > > > > Then you''d use a mock in your controller spec, and make sure you test > that > > your method is being called. > > > > > > On the other hand, the user model should be tested directly against > the > > db. > > > > > > HTH, > > > > > > Stefan > > > > > > > > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > > > > > > > > > > > > > Let''s say you''re using the restful_authentication plugin. > > > > > > > > > > > > You have a model called articles. On the index action of the > > articlescontroller you simply want to spec out that it''ll scope the > results > > to the ownership of the current_user. > > > > > > > > > > > > It should NOT include any articles other than the articles that user > > owns. > > > > > > > > > > > > How would you properly spec this out? > > > > > > > > > > > > Thanks for the help! > > > > _______________________________________________ > > > > rspec-users mailing list > > > > rspec-users at rubyforge.org > > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > > > > > > > > > -- > > > Bekk Open Source > > > http://boss.bekk.no > > > _______________________________________________ > > > 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 > > > > _______________________________________________ > > 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 >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071217/0b590545/attachment.html
On Dec 16, 2007 4:01 PM, Daniel N <has.sox at gmail.com> wrote:> > > > On Dec 17, 2007 8:43 AM, David Chelimsky <dchelimsky at gmail.com> wrote: > > > > On Dec 16, 2007 11:03 AM, Jonathan Linowes <jonathan at parkerhill.com> > wrote: > > > > > > btw, to answer the same question for member actions (such as show), you > can > > > stub or assert the association proxy class > > > > > > @article = current_user.articles.find(params[:id]) > > > > > > then, > > > > > > it "should find article scoped by current_user" do > > > article = mock_model(Article) > > > current_user.should_receive(:articles).and_return(Article) > > > Article.should_receive(:find).and_return(article) > > > get :show, :id => article.id > > > end > > > > > > this will ensure that your controller is not calling Article.find > unscoped > > > > I tend to take this one more step. I''m a bit of a demeter zealot, and > > I''m also usually writing the examples from the code first. So I''d do > > something like: > > > > it "should find the current users articles" do > > article = mock_model(Article) > > current_user.should_receive(:find_article).with("1").and_return(Article) > > get :show, :id => "1" > > end > > Where is current_user defined here? I''ve always stubbed current_user on the > controller object. How are you doing this one?Well that was just an example, not taken from any real code. You could either get it from the controller in the example: controller.current_user.should_receive(:find_article) or create a helper method to get at it.> > > > > > > > > This would lead me to add a find_article method to User: > > > > describe User do > > it "should find it''s own articles" do > > user = User.new > > user.articles.should_receive(:find).with("1") > > user.find_article("1) > > end > > end > > > > This has two benefits: > > - each example is simpler and focuses on one object and how it behaves > > - I can change the relationship between a User and it''s Articles > > without changing the controller code. > > > > FWIW, > > David > > > > > > > > > > > > > > > > linoj > > > > > > > > > > > > > > > On Dec 3, 2007, at 5:44 AM, Daniel N wrote: > > > Assuming that there is a call like this in your controller > > > > > > @articles = current_user.articles > > > > > > One way to do this is to stub out the controller.current_user to return > a > > > mock object of the current_user > > > > > > Then put an expectation on the current user that it''s articles method > gets > > > called. (return a mocked collection of articles) > > > > > > Then check that @articles is set to the returned mocked collection of > > > articles from current_user.articles > > > > > > phew... > > > > > > Ok So one way you might write this could be (This is untested...) > > > > > > it "should scope the articles to the currrent_user" do > > > > > > user = mock_model(User) > > > articles = [mock_model(Article)] > > > > > > controller.stub!(:current_user).and_return(user) > > > user.should_receive (:articles).and_return(articles) > > > > > > get :index > > > > > > assigns[:articles].should == articles > > > > > > end > > > > > > > > > Like I said though, that''s not tested itself. If that''s not exactly > > > right... it''s along the right track of an option that can work. > > > > > > HTH > > > Daniel > > > > > > On Dec 3, 2007 9:07 PM, Stefan Magnus Landr? <stefan.landro at gmail.com> > > > wrote: > > > > Typically, I''d write a method in your user model that returns the > user''s > > > articles: > > > > > > > > class User do > > > > > > > > def find_articles_for_user > > > > Article.find(:all, :conditions => [''userid = ?'', id) > > > > end > > > > > > > > end > > > > > > > > Then you''d use a mock in your controller spec, and make sure you test > that > > > your method is being called. > > > > > > > > On the other hand, the user model should be tested directly against > the > > > db. > > > > > > > > HTH, > > > > > > > > Stefan > > > > > > > > > > > > 2007/12/3, Fischer, Daniel <daniel at helpmebuyacar.org>: > > > > > > > > > > > > > > > > > > > > Let''s say you''re using the restful_authentication plugin. > > > > > > > > > > > > > > > You have a model called articles. On the index action of the > > > articlescontroller you simply want to spec out that it''ll scope the > results > > > to the ownership of the current_user. > > > > > > > > > > > > > > > It should NOT include any articles other than the articles that user > > > owns. > > > > > > > > > > > > > > > How would you properly spec this out? > > > > > > > > > > > > > > > Thanks for the help! > > > > > _______________________________________________ > > > > > rspec-users mailing list > > > > > rspec-users at rubyforge.org > > > > > http://rubyforge.org/mailman/listinfo/rspec-users > > > > > > > > > > > > > > > > > > > > > -- > > > > Bekk Open Source > > > > http://boss.bekk.no > > > > _______________________________________________ > > > > 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 > > > > > > _______________________________________________ > > > 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 > > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On Dec 16, 2007 1:43 PM, David Chelimsky <dchelimsky at gmail.com> wrote:> I tend to take this one more step. I''m a bit of a demeter zealot, and > I''m also usually writing the examples from the code first. So I''d do > something like: > > it "should find the current users articles" do > article = mock_model(Article) > current_user.should_receive(:find_article).with("1").and_return(Article) > get :show, :id => "1" > endI find that there are two problems with this approach: - since proxies provide so much behavior, wrapping the proxy''s methods like this can quickly lead to a bloated API on User - The Rails Way seems to care a lot less about demeter than you do. Even though the method name is obvious, you still get people going, "huh? why doesn''t he just do user.articles.find?" I''m right there with you in theory, but in practice I''ve found that people simply don''t like it. So I''ve just had to bite my tongue and write slightly uglier specs (I won''t give in on add_article, however. articles.should_receive(:<<) gives me sharp stomach pains) It has provided me a nice opportunity to express intent, though. Whenever I want a default finder that does slightly more than articles.find(1), I can write a find_article method to encapsulate it. Then when someone asks me, "well why don''t use you juse articles.find" I can reply that there''s a little more than meets the eye. But how great is it that they don''t have to know what it is in order to use it! Maybe there''s something to this approach after all. So like I said, in general I prefer your approach, but I''ve opted for the principle of least surprise with my coworkers. I think I make the best of it by communicating those times when I depart from the standard Rails chaining style. Pat