Hello RSpec users! I have one abstract class and a few classes that inherit from that abstract one. I''d like to test if my abstract class works with RSpec, but I can''t test directly abstract class (or can I?) and I don''t wanna test some particular class that inherits, because I wanna test general behaviour. So I was just wondering. Can I use mocking somehow to create a subclass of my base class, add some functionality in it and test methods of the base class? Hope that makes sense. Vojto Rinik http://infinite.sk ?Perfection is achieved perfection not when there is nothing left to add, but when there is nothing left to take away? ? Antoine de Saint-Exupery -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20100403/a792f1d6/attachment.html>
On Sat, Apr 3, 2010 at 8:56 AM, Vojto Rinik <zero0xxx at gmail.com> wrote:> Hello RSpec users! > I have one abstract class and a few classes that inherit from that abstract > one.Ruby doesn''t have abstract classes. You can have a base class that you don''t _intend_ to instantiate directly, but there''s nothing stopping you from doing so, so it''s not like an abstract class in java, which you actually can''t instantiate directly. I''ve seen some cases where the initialize method is made private so you can''t just call Foo.new, so it sort of feels like an abstract class, but even in that case you can still use send() to instantiate one in a test: AbstractIshClass.send(:new)> I''d like to test if my abstract class works with RSpec, but I can''t test > directly abstract > class (or can I?)Yes, you can. I''d either do that, or use a shared example group and apply it to all of the subclasses (see http://rspec.info/documentation/).> and I don''t wanna test some particular class that > inherits, because > I wanna test general behaviour. > So I was just wondering. Can I use mocking somehow to create a subclass of > my > base class, add some functionality in it and test methods of the base class?Mocks are for specifying interactions between objects, which is a different situation than you are describing. HTH, David
On 04/04/2010, at 7:32 AM, David Chelimsky wrote:> On Sat, Apr 3, 2010 at 8:56 AM, Vojto Rinik <zero0xxx at gmail.com> wrote: >> Hello RSpec users! >> I have one abstract class and a few classes that inherit from that abstract >> one. > > Ruby doesn''t have abstract classes. You can have a base class that you > don''t _intend_ to instantiate directly, but there''s nothing stopping > you from doing so, so it''s not like an abstract class in java, which > you actually can''t instantiate directly. > > I''ve seen some cases where the initialize method is made private so > you can''t just call Foo.new, so it sort of feels like an abstract > class, but even in that case you can still use send() to instantiate > one in a test: > > AbstractIshClass.send(:new) >How about if you overrode new and __new__ ? Julian.
On Sat, Apr 3, 2010 at 10:45 PM, Julian Leviston <julian at leviston.net> wrote:> > On 04/04/2010, at 7:32 AM, David Chelimsky wrote: > >> On Sat, Apr 3, 2010 at 8:56 AM, Vojto Rinik <zero0xxx at gmail.com> wrote: >>> Hello RSpec users! >>> I have one abstract class and a few classes that inherit from that abstract >>> one. >> >> Ruby doesn''t have abstract classes. You can have a base class that you >> don''t _intend_ to instantiate directly, but there''s nothing stopping >> you from doing so, so it''s not like an abstract class in java, which >> you actually can''t instantiate directly. >> >> I''ve seen some cases where the initialize method is made private so >> you can''t just call Foo.new, so it sort of feels like an abstract >> class, but even in that case you can still use send() to instantiate >> one in a test: >> >> ?AbstractIshClass.send(:new) >> > > How about if you overrode new and __new__ ?Then override the override. AFAIK, there''s really no preventing a client from using an object however it chooses in Ruby. You can make it difficult, but I''m pretty sure there''s always a way around it.
Sorry I meant send AND __send__ Julian. On 04/04/2010, at 11:45 AM, Julian Leviston wrote:> > On 04/04/2010, at 7:32 AM, David Chelimsky wrote: > >> On Sat, Apr 3, 2010 at 8:56 AM, Vojto Rinik <zero0xxx at gmail.com> wrote: >>> Hello RSpec users! >>> I have one abstract class and a few classes that inherit from that abstract >>> one. >> >> Ruby doesn''t have abstract classes. You can have a base class that you >> don''t _intend_ to instantiate directly, but there''s nothing stopping >> you from doing so, so it''s not like an abstract class in java, which >> you actually can''t instantiate directly. >> >> I''ve seen some cases where the initialize method is made private so >> you can''t just call Foo.new, so it sort of feels like an abstract >> class, but even in that case you can still use send() to instantiate >> one in a test: >> >> AbstractIshClass.send(:new) >> > > How about if you overrode new and __new__ ? > > Julian. > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
When I started programming Ruby and I wanted abstract classes I would raise an exception in the initialize method telling the client that they were trying to instantiate an abstract class. That was my best attempt at self-documenting code at the time. Nowadays, however, when I have behaviour that is abstract, I just put it in a module. That feels like much more idiomatic Ruby. On 4 Apr 2010, at 05:00, David Chelimsky wrote:> On Sat, Apr 3, 2010 at 10:45 PM, Julian Leviston > <julian at leviston.net> wrote: >> >> On 04/04/2010, at 7:32 AM, David Chelimsky wrote: >> >>> On Sat, Apr 3, 2010 at 8:56 AM, Vojto Rinik <zero0xxx at gmail.com> >>> wrote: >>>> Hello RSpec users! >>>> I have one abstract class and a few classes that inherit from >>>> that abstract >>>> one. >>> >>> Ruby doesn''t have abstract classes. You can have a base class that >>> you >>> don''t _intend_ to instantiate directly, but there''s nothing stopping >>> you from doing so, so it''s not like an abstract class in java, which >>> you actually can''t instantiate directly. >>> >>> I''ve seen some cases where the initialize method is made private so >>> you can''t just call Foo.new, so it sort of feels like an abstract >>> class, but even in that case you can still use send() to instantiate >>> one in a test: >>> >>> AbstractIshClass.send(:new) >>> >> >> How about if you overrode new and __new__ ? > > Then override the override. AFAIK, there''s really no preventing a > client from using an object however it chooses in Ruby. You can make > it difficult, but I''m pretty sure there''s always a way around it. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-userscheers, Matt http://mattwynne.net +447974 430184
Sounds like a lot of work On Apr 3, 2010, at 9:08 PM, Julian Leviston wrote:> Sorry I meant send AND __send__ > > Julian. > > On 04/04/2010, at 11:45 AM, Julian Leviston wrote: > >> >> On 04/04/2010, at 7:32 AM, David Chelimsky wrote: >> >>> On Sat, Apr 3, 2010 at 8:56 AM, Vojto Rinik <zero0xxx at gmail.com> wrote: >>>> Hello RSpec users! >>>> I have one abstract class and a few classes that inherit from that abstract >>>> one. >>> >>> Ruby doesn''t have abstract classes. You can have a base class that you >>> don''t _intend_ to instantiate directly, but there''s nothing stopping >>> you from doing so, so it''s not like an abstract class in java, which >>> you actually can''t instantiate directly. >>> >>> I''ve seen some cases where the initialize method is made private so >>> you can''t just call Foo.new, so it sort of feels like an abstract >>> class, but even in that case you can still use send() to instantiate >>> one in a test: >>> >>> AbstractIshClass.send(:new) >>> >> >> How about if you overrode new and __new__ ? >> >> Julian. >> >> >> _______________________________________________ >> 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 Apr 5, 2010, at 8:09 AM, Pat Maddox wrote:> > Sounds like a lot of work > > > On Apr 3, 2010, at 9:08 PM, Julian Leviston wrote: > >> Sorry I meant send AND __send__ >> >> Julian. >> >> On 04/04/2010, at 11:45 AM, Julian Leviston wrote: >> >>> >>> On 04/04/2010, at 7:32 AM, David Chelimsky wrote: >>> >>>> On Sat, Apr 3, 2010 at 8:56 AM, Vojto Rinik <zero0xxx at gmail.com> wrote: >>>>> Hello RSpec users! >>>>> I have one abstract class and a few classes that inherit from that abstract >>>>> one. >>>> >>>> Ruby doesn''t have abstract classes. You can have a base class that you >>>> don''t _intend_ to instantiate directly, but there''s nothing stopping >>>> you from doing so, so it''s not like an abstract class in java, which >>>> you actually can''t instantiate directly. >>>> >>>> I''ve seen some cases where the initialize method is made private so >>>> you can''t just call Foo.new, so it sort of feels like an abstract >>>> class, but even in that case you can still use send() to instantiate >>>> one in a test: >>>> >>>> AbstractIshClass.send(:new) >>>> >>> >>> How about if you overrode new and __new__ ? >>> >>> Julian.How about: class AbstractClassException < RuntimeError; end class AbstractishClass def initialize raise AbstractClassException.new("don''t do that.") end end That way, even sending a message to new causes a failure. And that''s what you''re looking for, right?
On Apr 5, 2010, at 9:37 PM, steve ross wrote:> On Apr 5, 2010, at 8:09 AM, Pat Maddox wrote: >> >> Sounds like a lot of work >> >> >> On Apr 3, 2010, at 9:08 PM, Julian Leviston wrote: >> >>> Sorry I meant send AND __send__ >>> >>> Julian. >>> >>> On 04/04/2010, at 11:45 AM, Julian Leviston wrote: >>> >>>> >>>> On 04/04/2010, at 7:32 AM, David Chelimsky wrote: >>>> >>>>> On Sat, Apr 3, 2010 at 8:56 AM, Vojto Rinik <zero0xxx at gmail.com> wrote: >>>>>> Hello RSpec users! >>>>>> I have one abstract class and a few classes that inherit from that abstract >>>>>> one. >>>>> >>>>> Ruby doesn''t have abstract classes. You can have a base class that you >>>>> don''t _intend_ to instantiate directly, but there''s nothing stopping >>>>> you from doing so, so it''s not like an abstract class in java, which >>>>> you actually can''t instantiate directly. >>>>> >>>>> I''ve seen some cases where the initialize method is made private so >>>>> you can''t just call Foo.new, so it sort of feels like an abstract >>>>> class, but even in that case you can still use send() to instantiate >>>>> one in a test: >>>>> >>>>> AbstractIshClass.send(:new) >>>>> >>>> >>>> How about if you overrode new and __new__ ? >>>> >>>> Julian. > > How about: > > class AbstractClassException < RuntimeError; end > class AbstractishClass > def initialize > raise AbstractClassException.new("don''t do that.") > end > end > > That way, even sending a message to new causes a failure. And that''s what you''re looking for, right?As Matt suggested earlier in this thread, this is not really idiomatic Ruby. If you want behavior in a structure that is not directly instantiable, use a module: module GeneralBehavior def something_general ... end end class SpecificClass include GeneralBehavior end describe GeneralBehavior do it "does something general" do klass = Class.new { include GeneralBehavior } klass.new.something_general.should ..... end end