Can I use mocking in this way?

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 R.

“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

On Sat, Apr 3, 2010 at 8:56 AM, Vojto R. [email protected] 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
RSpec 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 C. wrote:

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.

Sorry I meant send AND send

Julian.

On Sat, Apr 3, 2010 at 10:45 PM, Julian L. [email protected]
wrote:

you from doing so, so it’s not like an abstract class in java, which
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.

Sounds like a lot of work

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 C. wrote:

one.
one in a test:
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

cheers,
Matt

+447974 430184

On Apr 5, 2010, at 8:09 AM, Pat M. wrote:

On 04/04/2010, at 11:45 AM, Julian L. wrote:

don’t intend to instantiate directly, but there’s nothing stopping

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:

Ruby doesn’t have abstract classes. You can have a base class that you

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