Matt McNeil
2008-May-02 21:17 UTC
[rspec-users] spec''ing calls to super (or other Ruby keywords)
Hi there,
How does one spec an invocation of a Ruby keyword, such as super in this
case?
class User < ActiveResource::Base
# faking the ActiveRecord before/after_save observers
def save
super
UserMailer.deliver_activation(self) if recently_activated?
end
end
Does the solution look anything like the following?
describe User do
describe ''#save'' do
it "should call save on the parent class" do
# something.should_receive(:something)
@user.save
end
end
end
Any thoughts?
Thanks much,
Matt
--
View this message in context:
http://www.nabble.com/spec%27ing-calls-to-super-%28or-other-Ruby-keywords%29-tp17027929p17027929.html
Sent from the rspec-users mailing list archive at Nabble.com.
John D. Hume
2008-May-03 14:49 UTC
[rspec-users] spec''ing calls to super (or other Ruby keywords)
I believe calls to super are sufficiently internal to the Ruby interpreter that a mocking framework can''t intercept them without doing separate implementations for separate Ruby interpreters (and likely even separate versions). I could be wrong, but even so I''d recommend a different approach. If your need is really as simple as your example, what you have is just a method that has to get two things done: the base save and one additional call. You can write one (or more) example for each of those two things without your spec knowing that one of those things gets done by calling super. (You might object that by spec''ing the base #save behavior you''re spec''ing the framework. I''d say you''re USING the framework to spec something your code does. To be clear, I''m not suggesting you spec every detail of what save does: just something to make sure the record actually lands in the db.) (Sidebar: Keep in mind the return value if you''re really overriding #save like that.) If you''re dead set on spec''ing that the super method gets called, there are a couple of hideous ways of doing it that will leak out of your example. Namely, you can (in your spec) redefine the method in the superclass and verify it gets called or (also in your spec, and this one''s a little less leaky) have the class under test include a module that defines the same method and verify it gets called. Don''t do either of those though (unless it''s just to prove to yourself that they''re possible). -hume. On Fri, May 2, 2008 at 5:17 PM, Matt McNeil <nabble.108 at xoxy.net> wrote:> > Hi there, > > How does one spec an invocation of a Ruby keyword, such as super in this > case? > > class User < ActiveResource::Base > # faking the ActiveRecord before/after_save observers > def save > super > UserMailer.deliver_activation(self) if recently_activated? > end > end > > Does the solution look anything like the following? > > describe User do > describe ''#save'' do > it "should call save on the parent class" do > # something.should_receive(:something) > @user.save > end > end > end > > Any thoughts? > > Thanks much, > Matt > > -- > View this message in context: > http://www.nabble.com/spec%27ing-calls-to-super-%28or-other-Ruby-keywords%29-tp17027929p17027929.html > Sent from the rspec-users mailing list archive at Nabble.com. > > _______________________________________________ > 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/20080503/30f8647d/attachment.html>
Al Chou
2008-May-03 15:09 UTC
[rspec-users] spec''ing calls to super (or other Ruby keywords)
In the particular case of super, another approach, though perhaps not using the
spec framework, would be to assert (a la Test::Unit) that your class is a
subclass of the intended superclass. To be truly anal, also assert that the
superclass has a method with the same name as the subclass''s method of
interest and that the subclass has that method, too. But all this seems deeply
into the xUnit world, and far from the BDD way.
Al
----- Original Message ----
From: John D. Hume <duelin.markers at gmail.com>
To: rspec-users <rspec-users at rubyforge.org>
Sent: Saturday, May 3, 2008 7:49:11 AM
Subject: Re: [rspec-users] spec''ing calls to super (or other Ruby
keywords)
I believe calls to super are sufficiently internal to the Ruby interpreter that
a mocking framework can''t intercept them without doing separate
implementations for separate Ruby interpreters (and likely even separate
versions). I could be wrong, but even so I''d recommend a different
approach.
If your need is really as simple as your example, what you have is just a method
that has to get two things done: the base save and one additional call. You can
write one (or more) example for each of those two things without your spec
knowing that one of those things gets done by calling super. (You might object
that by spec''ing the base #save behavior you''re
spec''ing the framework. I''d say you''re USING the
framework to spec something your code does. To be clear, I''m not
suggesting you spec every detail of what save does: just something to make sure
the record actually lands in the db.)
(Sidebar: Keep in mind the return value if you''re really overriding
#save like that.)
If you''re dead set on spec''ing that the super method gets
called, there are a couple of hideous ways of doing it that will leak out of
your example. Namely, you can (in your spec) redefine the method in the
superclass and verify it gets called or (also in your spec, and this
one''s a little less leaky) have the class under test include a module
that defines the same method and verify it gets called. Don''t do
either of those though (unless it''s just to prove to yourself that
they''re possible).
-hume.
On Fri, May 2, 2008 at 5:17 PM, Matt McNeil <nabble.108 at xoxy.net>
wrote:
Hi there,
How does one spec an invocation of a Ruby keyword, such as super in this
case?
class User < ActiveResource::Base
# faking the ActiveRecord before/after_save observers
def save
super
UserMailer.deliver_activation(self) if recently_activated?
end
end
Does the solution look anything like the following?
describe User do
describe ''#save'' do
it "should call save on the parent class" do
# something.should_receive(:something)
@user.save
end
end
end
Any thoughts?
Thanks much,
Matt
____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile. Try it now.
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://rubyforge.org/pipermail/rspec-users/attachments/20080503/e662023c/attachment-0001.html>
Scott Taylor
2008-May-03 20:51 UTC
[rspec-users] spec''ing calls to super (or other Ruby keywords)
On May 3, 2008, at 11:09 AM, Al Chou wrote:> In the particular case of super, another approach, though perhaps > not using the spec framework, would be to assert (a la Test::Unit) > that your class is a subclass of the intended superclass. To be > truly anal, also assert that the superclass has a method with the > same name as the subclass''s method of interest and that the subclass > has that method, too. But all this seems deeply into the xUnit > world, and far from the BDD way. > > AlThe truth is that you shouldn''t be spec''ing calls to the super "method", but rather the behaviour of super. One quick way to do this is as so: [BaseClass, Subclass].each { |klass| it "should do whatever super does" do klass.new.foo_bar.should == :baz end end Your original example is a little trickier, because you didn''t write the base class, and you probably aren''t going to spec it out. There''s obviously great complexity in that call to super. Now you know why none of us like writing specs against rails apps. Scott> > > ----- Original Message ---- > From: John D. Hume <duelin.markers at gmail.com> > To: rspec-users <rspec-users at rubyforge.org> > Sent: Saturday, May 3, 2008 7:49:11 AM > Subject: Re: [rspec-users] spec''ing calls to super (or other Ruby > keywords) > > I believe calls to super are sufficiently internal to the Ruby > interpreter that a mocking framework can''t intercept them without > doing separate implementations for separate Ruby interpreters (and > likely even separate versions). I could be wrong, but even so I''d > recommend a different approach. > > If your need is really as simple as your example, what you have is > just a method that has to get two things done: the base save and one > additional call. You can write one (or more) example for each of > those two things without your spec knowing that one of those things > gets done by calling super. (You might object that by spec''ing the > base #save behavior you''re spec''ing the framework. I''d say you''re > USING the framework to spec something your code does. To be clear, > I''m not suggesting you spec every detail of what save does: just > something to make sure the record actually lands in the db.) > > (Sidebar: Keep in mind the return value if you''re really overriding > #save like that.) > > If you''re dead set on spec''ing that the super method gets called, > there are a couple of hideous ways of doing it that will leak out of > your example. Namely, you can (in your spec) redefine the method in > the superclass and verify it gets called or (also in your spec, and > this one''s a little less leaky) have the class under test include a > module that defines the same method and verify it gets called. > Don''t do either of those though (unless it''s just to prove to > yourself that they''re possible). > > -hume. > > > On Fri, May 2, 2008 at 5:17 PM, Matt McNeil <nabble.108 at xoxy.net> > wrote: > > Hi there, > > How does one spec an invocation of a Ruby keyword, such as super in > this > case? > > class User < ActiveResource::Base > # faking the ActiveRecord before/after_save observers > def save > super > UserMailer.deliver_activation(self) if recently_activated? > end > end > > Does the solution look anything like the following? > > describe User do > describe ''#save'' do > it "should call save on the parent class" do > # something.should_receive(:something) > @user.save > end > end > end > > Any thoughts? > > Thanks much, > Matt > > Be a better friend, newshound, and know-it-all with Yahoo! Mobile. > Try it now._______________________________________________ > 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/20080503/68c6543d/attachment-0001.html>
Al Chou
2008-May-03 22:58 UTC
[rspec-users] spec''ing calls to super (or other Ruby keywords)
Funny, I mostly like writing RSpec specs for Rails, aside from the fact that it
sometimes takes me a while to figure out exactly how and what I need to write to
specify what I want to specify.
In any case, I agree that the spec should specify what the method achieves, not
the fact that the method calls super.
Al
----- Original Message ----
From: Scott Taylor <mailing_lists at railsnewbie.com>
To: rspec-users <rspec-users at rubyforge.org>
Sent: Saturday, May 3, 2008 1:51:51 PM
Subject: Re: [rspec-users] spec''ing calls to super (or other Ruby
keywords)
On May 3, 2008, at 11:09 AM, Al Chou wrote:
In the particular case of super, another approach, though perhaps not using the
spec framework, would be to assert (a la Test::Unit) that your class is a
subclass of the intended superclass. To be truly anal, also assert that the
superclass has a method with the same name as the subclass''s method of
interest and that the subclass has that method, too. But all this seems deeply
into the xUnit world, and far from the BDD way.
Al
The truth is that you shouldn''t be spec''ing calls to the super
"method", but rather the behaviour of super. One quick way to do this
is as so:
[BaseClass, Subclass].each { |klass|
it "should do whatever super does" do
klass.new.foo_bar.should == :baz
end
end
Your original example is a little trickier, because you didn''t write
the base class, and you probably aren''t going to spec it out.
There''s obviously great complexity in that call to super. Now you know
why none of us like writing specs against rails apps.
Scott
----- Original Message ----
From: John D. Hume <duelin.markers at gmail.com>
To: rspec-users <rspec-users at rubyforge.org>
Sent: Saturday, May 3, 2008 7:49:11 AM
Subject: Re: [rspec-users] spec''ing calls to super (or other Ruby
keywords)
I believe calls to super are sufficiently internal to the Ruby interpreter that
a mocking framework can''t intercept them without doing separate
implementations for separate Ruby interpreters (and likely even separate
versions). I could be wrong, but even so I''d recommend a different
approach.
If your need is really as simple as your example, what you have is just a method
that has to get two things done: the base save and one additional call. You can
write one (or more) example for each of those two things without your spec
knowing that one of those things gets done by calling super. (You might object
that by spec''ing the base #save behavior you''re
spec''ing the framework. I''d say you''re USING the
framework to spec something your code does. To be clear, I''m not
suggesting you spec every detail of what save does: just something to make sure
the record actually lands in the db.)
(Sidebar: Keep in mind the return value if you''re really overriding
#save like that.)
If you''re dead set on spec''ing that the super method gets
called, there are a couple of hideous ways of doing it that will leak out of
your example. Namely, you can (in your spec) redefine the method in the
superclass and verify it gets called or (also in your spec, and this
one''s a little less leaky) have the class under test include a module
that defines the same method and verify it gets called. Don''t do
either of those though (unless it''s just to prove to yourself that
they''re possible).
-hume.
On Fri, May 2, 2008 at 5:17 PM, Matt McNeil <nabble.108 at xoxy.net>
wrote:
Hi there,
How does one spec an invocation of a Ruby keyword, such as super in this
case?
class User < ActiveResource::Base
# faking the ActiveRecord before/after_save observers
def save
super
UserMailer.deliver_activation(self) if recently_activated?
end
end
Does the solution look anything like the following?
describe User do
describe ''#save'' do
it "should call save on the parent class" do
# something.should_receive(:something)
@user.save
end
end
end
Any thoughts?
Thanks much,
Matt
____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile. Try it now.
http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://rubyforge.org/pipermail/rspec-users/attachments/20080503/fd0d0d6d/attachment.html>