[rspec-users] Isolating rails model specs from their implementation

Russell Tracey
2007-07-29T19:50:30Z

I''m currently taking a Rails project management app I built when
learning Rails and adding specs to it. During the course of building
the app the requirement that project should be archiveable was added.
So a project is in one of two states active or archived.

This led to the creation of the following methods:

Project.active_projects
Project.archived_projects

@project.active?
@project.archived?
@project.archive!
@project.unarchive!

The current implementation of this is using a separate table of
"visibilities" as follows:

# Implementation 1 (Current)

Tables:

  Project
    id name           visibility_status_id
    1  ActiveProject                        1
    1  ArchivedProject                     2

  VisibilityStatuses
    id name
    1  Live
    2  Archived

But the same behavior could be implemented using a datetime column as follows:

# Implementation 2

Tables:

  Project
    id name            archived_at
    1  ActiveProject   null
    1  ArchivedProject 2007-07-29:18:57

Or in fact numerous other ways e.g.

# Implementation 3

Army of cows:

Each cow represents a project, the cows wear one of two hats
to indicate the active/archived status of the project they represent.

...and so on.

It''s my understanding that model specs (and specs in general) should
be shielded from the implementation details, so how do i check that
Project.active_projects only returns active projects without looking
at assuming something about the implementation? My initial thought is
to check each of them using one of the other exposed methods above, in
this case...

  Project.active_projects.all? {|p| p.active? }

but then i can''t work out how to spec all the other methods without
going round in circles so that each spec would end up assuming that
the other methods work (in this case that p.active? is working) or
worse resorting to peeking at implementation details.

Russell Tracey