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
on 2008-01-10 19:36
on 2008-01-10 19:40
On Jan 10, 2008 12:35 PM, Chris Kampmeier <chris@kampers.net> wrote: > > 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?
on 2008-01-10 20:08
On 1/10/08, David Chelimsky <dchelimsky@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
on 2008-01-10 20:19
On 1/10/08, Chris Kampmeier <chris@kampers.net> wrote: > that object to act like a Rails association -- so it should respond to > 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/
on 2008-01-10 20:39
On 1/10/08, Rick DeNatale <rick.denatale@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
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.