5

I have a module like this (but more complicated):

module Aliasable 
  def self.included(base)
    base.has_many :aliases, :as => :aliasable
  end
end

which I include in several models. Currently for testing I make another module as below, which I just include in the test case

module AliasableTest 
  def self.included(base)
    base.class_exec do 
      should have_many(:aliases)
    end
  end
end

The question is how do I go about testing this module in isolation? Or is the above way good enough. Seems like there is probably a better way to do it.

mike
  • 431
  • 3
  • 8

1 Answers1

8

First off, self.included is not a good way to describe your modules, and class_exec is needlessly complicating things. Instead, you should extend ActiveSupport::Concern, as in:

module Phoneable
  extend ActiveSupport::Concern

  included do
    has_one :phone_number
    validates_uniqueness_of :phone_number
  end
end

You didn't mention what test framework you're using, but RSpec covers exactly this case. Try this:

shared_examples_for "a Phoneable" do
  it "should have a phone number" do
    subject.should respond_to :phone_number
  end
end

Assuming your models look like:

class Person              class Business
  include Phoneable         include Phoneable
end                       end

Then, in your tests, you can do:

describe Person do
  it_behaves_like "a Phoneable"      # reuse Phoneable tests

  it "should have a full name" do
    subject.full_name.should == "Bob Smith"
  end
end

describe Business do
  it_behaves_like "a Phoneable"      # reuse Phoneable tests

  it "should have a ten-digit tax ID" do
    subject.tax_id.should == "123-456-7890"
  end
end
John Feminella
  • 303,634
  • 46
  • 339
  • 357
  • Thanks, that is super helpful. Do you know of the correct way to do it with Test::Unit (and shoulda)? – mike Jul 12 '11 at 23:28
  • As far as I know, Test::Unit doesn't have a similar facility. Of course, you could always just make a module like `PhoneableTests` in this example and then reuse it by including that. – John Feminella Jul 13 '11 at 00:14
  • I will mark this as a correct answer and I might ask a different question about shoulda then, or maybe I should just jump on the RSpec band wagon. – mike Jul 13 '11 at 19:51