Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing a module that is included in ActiveRecord models

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.

like image 723
mike Avatar asked Jul 11 '11 23:07

mike


People also ask

What is Unit Testing in Ruby on Rails?

The Tests − They are test applications that produce consistent result and prove that a Rails application does what it is expected to do. Tests are developed concurrently with the actual application. The Assertion − This is a one line of code that evaluates an object (or expression) for expected results.

What is unit testing and how it is done?

Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation. This testing methodology is done during the development process by the software developers and sometimes QA staff.

What type of test is not typical in a Rails application?

Don't write view tests. You should be able to change copy or HTML classes without breaking your tests. Just assess critical view elements as part of your in-browser integration tests.


1 Answers

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
like image 135
John Feminella Avatar answered Sep 20 '22 08:09

John Feminella