[rspec-users] spec'ing metaprograming & rails CRUD

Scott Taylor mailing_lists at railsnewbie.com
Sat Mar 24 05:11:04 EDT 2007

For edge rails there is a Crud generator.  There is also a CRUD  
controller that is out there from which you can inherit your other  
controllers (see http://geekonomics.blogspot.com/2006/07/crud-and- 

This got me thinking about Crud controllers in general.  As far as I  
know, the generator can't produce crud classes which are nested  
(i.e. /posts/1/comments/7).  So I thought about creating my own Crud  
class from which to inherit from, with some private methods, like so:

class CrudController < ActiveRecord::Base
   class << self
     def model
      # get a default name based on the controller name
      # or specify a name

     def belongs_to
       # the model's "belongs_to"/foreign key relationship
       # this could also be found dynamically

class CommentsController < CrudController
   model :comments
   belongs_to :post

And then this would generate the typical nested crud, with  
before_filter and all of that jazz

Anyway, here goes my question.  The CrudController's specs should set  
a bunch of instance variables (such as @comments = @post.comments)  
and a bunch of instance methods in the Comments controller.  How  
would I spec out such a thing?  I would have to use reflection in The  
CRUD controller - do a bunch of no-no's, like use  
private_instance_methods, send, etc. to get to the private class methods

So It looks like I should just create a CommentsController instance,  
and spec that.  But now how do I practice test-first development on  
the CrudController?

I have also been thinking a little bit about the specs of Rubinius.   
I have no idea how it is implemented, but I'm sure each class will  
have a symbol table, etc. etc.  The high level spec's will look  
something like the following:

   specify "+ should concatenate two arrays" do
     example do
       [ 1, 2, 3 ] + [ 4, 5 ]
     end.should == [1, 2, 3, 4, 5]

How Rubininus creates the Arrays, sets them up in the symbol table/ 
creates an object id, etc. - All of this, the spec will never touch.   
How is one to do test first development on this sort of thing?  If  
the methods involved get too big, they will probably be refactored  
into private methods.  So how does one practice BDD on private  
methods?  Or should one just assume that they will work?

These sorts of things are the things I was thinking about in my last  
email.  As I see it, spec'ing/testing is used for the following:
1. Verification of Code Working the way you expect it to.  This is  
more fine grained, and better suited to Test::Unit, although the code  
can easily break after refactoring.
2.  Documentation
3. Test-First development.  What small piece do I implement next?  
(Think of the Rubinus/private methods example)
4. Defining Behaviour, which of course, is simply high level  
verification on exposed methods.

Thoughts on these matters?


More information about the rspec-users mailing list