How to write specification for the *base* class API?

For the base class, it seems reasonable to specify public API with
RSpec.

However, since we deal with a base class, methods are often empty (put
there just to show the API).

The spec cannot be run against the base class. In consequence, the spec
must be duplicated in every derived class, which seems to be far from
DRY.

How to deal with it? What is THE RSpec way to specify APIs when we face
inheritance?

On Tue, Jul 15, 2008 at 4:17 AM, Piotr W. [email protected]
wrote:

How to deal with it? What is THE RSpec way to specify APIs when we face
inheritance?

This is more a theoretical TDD/BDD question than an RSpec question.

There are a few schools of thought about this, so I’d recommend
checking out the testdrivendevelopment list at yahoo as well - but
I’ll give you my two cents :slight_smile:

Any subclass can override any method in the base class, so it is not
sufficient to have examples of just the base class, nor is it very
helpful to have examples for empty methods just for show if the intent
is that the base class will never get initialized directly.

If you’re deriving objects from the base class, write examples for the
derived classes. If all derived classes are intended to pass the same
examples with the same input/output expectations, then you can write
shared examples and run them against instances of all the derived
classes, thus satisfying your quest for DRY.

HTH,
David

On Tue, Jul 15, 2008 at 5:17 AM, Piotr W. [email protected]
wrote:

For the base class, it seems reasonable to specify public API with
RSpec.

However, since we deal with a base class, methods are often empty (put
there just to show the API).

What’s the point of that? This isn’t Java.

The spec cannot be run against the base class. In consequence, the spec
must be duplicated in every derived class, which seems to be far from
DRY.

Presumably the derived classes have different implementations, so you
would need to spec them out differently.

If the implementations are the same, shared behaviors are often useful.

Pat

On 15-jul-2008, at 14:47, Pat M. wrote:

On Tue, Jul 15, 2008 at 5:17 AM, Piotr W. <lists@ruby-
forum.com> wrote:

For the base class, it seems reasonable to specify public API with
RSpec.

However, since we deal with a base class, methods are often empty
(put
there just to show the API).

What’s the point of that? This isn’t Java.

Exactly. In all of my projects, I only have an inheritance tree of at
most 3 levels deep. AR::Base → Generic → Specific model.
If there are more than three levels, something might not be okay with
the design of your app. Of course your mileage may vary, but I think
a lot of developers will agree on this subject.

On Tue, Jul 15, 2008 at 8:47 AM, Pat M. [email protected] wrote:

Readability I would assume. Rspec does this in the base_formatter.rb and
Rails does this in some places as well I have noticed.

On 15-jul-2008, at 15:22, Piotr W. wrote:

It’s not AR. I have 2 levels: Site1Scraper < BaseScraper.

Ok, but if a method is only in a BaseScraper for documentational
purposes, eg, an empty body, should it be defined on that model at
all? If it’s only going to be used on a Site1Scraper, leave it to
that class to define and have it tested there.
As far as I know there’s no useful implementation of an interface or
an abstract class in ruby, but I could be wrong.

However, since we deal with a base class, methods are often empty
(put there just to show the API).

What’s the point of that? This isn’t Java.

Documentation for developers of derived classes.

Exactly. In all of my projects, I only have an inheritance tree of
at most 3 levels deep.

It’s not AR. I have 2 levels: Site1Scraper < BaseScraper.

There will be many SiteXScrapers implemented by several people.

++++

From your answers I conclude it’s not possible (or at least not
recommended) to document abstract interface with RSpec.