Chris Kampmeier
2008-Jan-10 18:35 UTC
[rspec-users] Mocking and stubbing Rails'' association extensions
I''m having a lot of trouble stubbing out an association extension for some view tests. Example rails code modeling a music album: class Album < ActiveRecord::Base has_many :songs do def streamable find(:all, :conditions => ''streamable = 1'') end end end So for a given Album instance (say @album), I need to be able to stub both @album.songs and @album.songs.streamable in the same before block. Is there a way for a stub to return one thing when called alone (@album.songs) and another stub when the call is chained? (@album.songs.streamable) Before adding the extension, I just had @album.songs returning an array of Song instances. The only thing I''ve thought of that would work is temporarily extending Array itself to respond to #streamable, but that feels ugly. Thanks for any ideas, Chris Kampmeier http://www.shiftcommathree.com -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2417 bytes Desc: not available Url : http://rubyforge.org/pipermail/rspec-users/attachments/20080110/57baee23/attachment.bin
David Chelimsky
2008-Jan-10 18:40 UTC
[rspec-users] Mocking and stubbing Rails'' association extensions
On Jan 10, 2008 12:35 PM, Chris Kampmeier <chris at kampers.net> wrote:> I''m having a lot of trouble stubbing out an association extension for > some view tests. Example rails code modeling a music album: > > class Album < ActiveRecord::Base > has_many :songs do > def streamable > find(:all, :conditions => ''streamable = 1'') > end > end > end > > So for a given Album instance (say @album), I need to be able to stub > both @album.songs and @album.songs.streamable in the same before block. > > Is there a way for a stub to return one thing when called alone > (@album.songs) and another stub when the call is chained? > (@album.songs.streamable) > > Before adding the extension, I just had @album.songs returning an > array of Song instances. The only thing I''ve thought of that would > work is temporarily extending Array itself to respond to #streamable, > but that feels ugly.album = mock("album") songs = mock("songs") album.stub!(:songs).and_return(songs) songs.stub!(:streamable).and_return(true) That''s the general idea. Specifics will vary for each example. Cool?> > Thanks for any ideas, > > Chris Kampmeier > http://www.shiftcommathree.com > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Chris Kampmeier
2008-Jan-10 19:07 UTC
[rspec-users] Mocking and stubbing Rails'' association extensions
On 1/10/08, David Chelimsky <dchelimsky at gmail.com> wrote:> album = mock("album") > songs = mock("songs") > album.stub!(:songs).and_return(songs) > songs.stub!(:streamable).and_return(true) > > That''s the general idea. Specifics will vary for each example.If I do this, I end up with a mock object when I call @album.songs. I need that object to act like a Rails association -- so it should respond to #each, #first, and all our other Enumerable friends, since my view iterates over it, as well as the stubbed call to #streamable, which returns a "filtered" version of the assocation (see Rails code in OP). But I certainly don''t want to start stubbing Enumerable methods. # Let''s say song1, song2, and song3 are instances of Song. # Song has a boolean attribute, streamable. # song1.streamable? => true # song2.streamable? => true # song3.streamable? => false album = mock("album") songs = mock("songs") album.stub!(:songs).and_return(songs) songs.stub!(:streamable).and_return([song1, song2]) So now album.songs.streamable returns [song1, song2] -- perfect. But I need album.songs to return [song1, song2, song3] as well. That''s the problem. I hope that''s a little clearer. Thanks for the help. Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20080110/b151afac/attachment.html
Rick DeNatale
2008-Jan-10 19:19 UTC
[rspec-users] Mocking and stubbing Rails'' association extensions
On 1/10/08, Chris Kampmeier <chris at kampers.net> wrote:> On 1/10/08, David Chelimsky <dchelimsky at gmail.com> wrote: > > > album = mock("album") > > songs = mock("songs") > > album.stub!(:songs).and_return(songs) > > songs.stub!(:streamable).and_return(true) > > > > That''s the general idea. Specifics will vary for each example. > > If I do this, I end up with a mock object when I call @album.songs. I need > that object to act like a Rails association -- so it should respond to > #each, #first, and all our other Enumerable friends, since my view iterates > over it, as well as the stubbed call to #streamable, which returns a > "filtered" version of the assocation (see Rails code in OP). But I certainly > don''t want to start stubbing Enumerable methods. > > # Let''s say song1, song2, and song3 are instances of Song. > # Song has a boolean attribute, streamable. > # song1.streamable? => true > # song2.streamable? => true > # song3.streamable? => false > album = mock("album") > songs = mock("songs") > album.stub!(:songs).and_return(songs) > songs.stub!(:streamable).and_return([song1, song2]) > > So now album.songs.streamable returns [song1, song2] -- perfect. But I need > album.songs to return [song1, song2, song3] as well. That''s the problem.So why not songs = [song1, song2, song3] album.stub!(:songs).and_return(songs) songs.stub!(:streamable).and_return([song1, song2]) -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
Chris Kampmeier
2008-Jan-10 19:38 UTC
[rspec-users] Mocking and stubbing Rails'' association extensions
On 1/10/08, Rick DeNatale <rick.denatale at gmail.com> wrote:> > So why not > > songs = [song1, song2, song3] > album.stub!(:songs).and_return(songs) > songs.stub!(:streamable).and_return([song1, song2])Oh, of course. Thank you. I think my mind was in a rut of "must use mock or mock_model" and I didn''t think to just stub a method call on an existing array. Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20080110/db2d6c94/attachment.html