Rails model association collections allow you to do nifty things like:
article.comments.find(:all, :conditions => {:created_at > 1.day.ago})
Has anyone found a good way to mock this up? I''m currently doing this:
@comment1 = mock_model(Comment)
comments = mock(Array)
comments.stub!(:find).and_return([@comment1])
@article = mock_model(Article)
@article.stub!(:comments).and_return(comments)
I don''t like this, because of that intermediate
''comments'' object, whose
only purpose is so that i can stub the chained method. I''d like to do
something like this:
@comment1 = mock_model(Comment)
@article = mock_model(Article, :comments => mock(Array, :find =>
[@comment1]))
But trying this causes an error: "Mock ''Array'' received
unexpected
message :find with (:all, ...)" because you can''t inline stubs
with
ordinary `mock`. I can replace it with `mock_model`, but this feels unclean.
Has anyone come across a good ''best-practice'' solution to this
problem?
TIA,
Paul Sadauskas
On 7/18/07, Paul <psadauskas at absolute-performance.com> wrote:> Rails model association collections allow you to do nifty things like: > > article.comments.find(:all, :conditions => {:created_at > 1.day.ago}) > > Has anyone found a good way to mock this up? I''m currently doing this: > > @comment1 = mock_model(Comment) > comments = mock(Array) > comments.stub!(:find).and_return([@comment1]) > > @article = mock_model(Article) > @article.stub!(:comments).and_return(comments) > > I don''t like this, because of that intermediate ''comments'' object, whose > only purpose is so that i can stub the chained method. I''d like to do > something like this: > > @comment1 = mock_model(Comment) > > @article = mock_model(Article, :comments => mock(Array, :find => > [@comment1])) > > But trying this causes an error: "Mock ''Array'' received unexpected > message :find with (:all, ...)" because you can''t inline stubs with > ordinary `mock`. I can replace it with `mock_model`, but this feels unclean. > > Has anyone come across a good ''best-practice'' solution to this problem?You can use the stub() method instead of mock() to inline method stubs: @article = mock_model( Article, :comments => stub(Array, :find => [@comment1]) ) The mock() method works differently because it does different stuff w/ the Hash under the covers.> > TIA, > Paul Sadauskas > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Any chance of some prettier syntax for that? ------- Courtenay On Jul 18, 2007, at 2:30 PM, "David Chelimsky" <dchelimsky at gmail.com> wrote:> On 7/18/07, Paul <psadauskas at absolute-performance.com> wrote: >> Rails model association collections allow you to do nifty things >> like: >> >> article.comments.find(:all, :conditions => {:created_at > >> 1.day.ago}) >> >> Has anyone found a good way to mock this up? I''m currently doing >> this: >> >> @comment1 = mock_model(Comment) >> comments = mock(Array) >> comments.stub!(:find).and_return([@comment1]) >> >> @article = mock_model(Article) >> @article.stub!(:comments).and_return(comments) >> >> I don''t like this, because of that intermediate ''comments'' object, >> whose >> only purpose is so that i can stub the chained method. I''d like to do >> something like this: >> >> @comment1 = mock_model(Comment) >> >> @article = mock_model(Article, :comments => mock(Array, :find => >> [@comment1])) >> >> But trying this causes an error: "Mock ''Array'' received unexpected >> message :find with (:all, ...)" because you can''t inline stubs with >> ordinary `mock`. I can replace it with `mock_model`, but this feels >> unclean. >> >> Has anyone come across a good ''best-practice'' solution to this >> problem? > > You can use the stub() method instead of mock() to inline method > stubs: > > @article = mock_model( > Article, :comments => stub(Array, :find => [@comment1]) > ) > > The mock() method works differently because it does different stuff w/ > the Hash under the covers. > >> >> TIA, >> Paul Sadauskas >> >> _______________________________________________ >> 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
Any chance of some prettier syntax for that? ------- Courtenay On Jul 18, 2007, at 2:30 PM, "David Chelimsky" <dchelimsky at gmail.com> wrote:> On 7/18/07, Paul <psadauskas at absolute-performance.com> wrote: >> Rails model association collections allow you to do nifty things >> like: >> >> article.comments.find(:all, :conditions => {:created_at > 1.day.ago}) >> >> Has anyone found a good way to mock this up? I''m currently doing >> this: >> >> @comment1 = mock_model(Comment) >> comments = mock(Array) >> comments.stub!(:find).and_return([@comment1]) >> >> @article = mock_model(Article) >> @article.stub!(:comments).and_return(comments) >> >> I don''t like this, because of that intermediate ''comments'' object, >> whose >> only purpose is so that i can stub the chained method. I''d like to do >> something like this: >> >> @comment1 = mock_model(Comment) >> >> @article = mock_model(Article, :comments => mock(Array, :find => >> [@comment1])) >> >> But trying this causes an error: "Mock ''Array'' received unexpected >> message :find with (:all, ...)" because you can''t inline stubs with >> ordinary `mock`. I can replace it with `mock_model`, but this feels >> unclean. >> >> Has anyone come across a good ''best-practice'' solution to this >> problem? > > You can use the stub() method instead of mock() to inline method > stubs: > > @article = mock_model( > Article, :comments => stub(Array, :find => [@comment1]) > ) > > The mock() method works differently because it does different stuff w/ > the Hash under the covers. > >> >> TIA, >> Paul Sadauskas >> >> _______________________________________________ >> 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
I eventually ended up using this, from a somewhat-related post to this
list a couple months ago:
def assoc_mock(stubs = {})
proxy = mock(''association_proxy'')
stubs.each do |method, ret|
proxy.stub!(method).and_return(ret)
end
proxy
end
Then I can do something like I wanted:
@comment = mock_model(Comment)
@article = mock_model(Article, :comments => (@comment = assoc_mock(:find
=> [@comment])))
But this works just like the stub!(Foo, :method => return). I might keep
mine, though, its a little more explicit as to what the
''in-between''
collection is.
Thanks,
Paul
David Chelimsky wrote:> On 7/18/07, Paul <psadauskas at absolute-performance.com> wrote:
>
>> Rails model association collections allow you to do nifty things like:
>>
>> article.comments.find(:all, :conditions => {:created_at >
1.day.ago})
>>
>> Has anyone found a good way to mock this up? I''m currently
doing this:
>>
>> @comment1 = mock_model(Comment)
>> comments = mock(Array)
>> comments.stub!(:find).and_return([@comment1])
>>
>> @article = mock_model(Article)
>> @article.stub!(:comments).and_return(comments)
>>
>> I don''t like this, because of that intermediate
''comments'' object, whose
>> only purpose is so that i can stub the chained method. I''d
like to do
>> something like this:
>>
>> @comment1 = mock_model(Comment)
>>
>> @article = mock_model(Article, :comments => mock(Array, :find
=>
>> [@comment1]))
>>
>> But trying this causes an error: "Mock ''Array''
received unexpected
>> message :find with (:all, ...)" because you can''t inline
stubs with
>> ordinary `mock`. I can replace it with `mock_model`, but this feels
unclean.
>>
>> Has anyone come across a good ''best-practice''
solution to this problem?
>>
>
> You can use the stub() method instead of mock() to inline method stubs:
>
> @article = mock_model(
> Article, :comments => stub(Array, :find => [@comment1])
> )
>
> The mock() method works differently because it does different stuff w/
> the Hash under the covers.
>
>
>> TIA,
>> Paul Sadauskas
>>
>> _______________________________________________
>> 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 7/18/07, court3nay <court3nay at gmail.com> wrote:> Any chance of some prettier syntax for that?There''s always a chance. What do you propose?> > ------- > Courtenay > > On Jul 18, 2007, at 2:30 PM, "David Chelimsky" <dchelimsky at gmail.com> > wrote: > > > On 7/18/07, Paul <psadauskas at absolute-performance.com> wrote: > >> Rails model association collections allow you to do nifty things > >> like: > >> > >> article.comments.find(:all, :conditions => {:created_at > > >> 1.day.ago}) > >> > >> Has anyone found a good way to mock this up? I''m currently doing > >> this: > >> > >> @comment1 = mock_model(Comment) > >> comments = mock(Array) > >> comments.stub!(:find).and_return([@comment1]) > >> > >> @article = mock_model(Article) > >> @article.stub!(:comments).and_return(comments) > >> > >> I don''t like this, because of that intermediate ''comments'' object, > >> whose > >> only purpose is so that i can stub the chained method. I''d like to do > >> something like this: > >> > >> @comment1 = mock_model(Comment) > >> > >> @article = mock_model(Article, :comments => mock(Array, :find => > >> [@comment1])) > >> > >> But trying this causes an error: "Mock ''Array'' received unexpected > >> message :find with (:all, ...)" because you can''t inline stubs with > >> ordinary `mock`. I can replace it with `mock_model`, but this feels > >> unclean. > >> > >> Has anyone come across a good ''best-practice'' solution to this > >> problem? > > > > You can use the stub() method instead of mock() to inline method > > stubs: > > > > @article = mock_model( > > Article, :comments => stub(Array, :find => [@comment1]) > > ) > > > > The mock() method works differently because it does different stuff w/ > > the Hash under the covers. > > > >> > >> TIA, > >> Paul Sadauskas > >> > >> _______________________________________________ > >> 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 >