Search code examples
ruby-on-railsrubyrspecshoulda

Rspec and Shoulda - complementary or alternatives?


I've used Shoulda for a while, and I've read and played with Rspec. I have not done an in-depth compare and contrast. But it seems to me like there is some overlap between the two, but that they are not 1-1 replacements.

I am considering writing some unit tests in my Rails system with Rspec, without replacing all the existing tests that are written with Shoulda. Just as a way to get the feel.

Is this a good idea? Can I gradually move from one to the other or am I asking for trouble?

Any clear cut advantages of one over the other that I should consider?


Solution

  • I have to argue against Chris's answer that they are alternatives. I use Shoulda and Rspec together in my Rails application, and they complement each other well.

    This combo allows me to write concise one-line unit tests for recurring things like associations and validations, as well as the having the full rspec suite for more complex specs. You get the best of both worlds without any conflicts.

    Check out the Shoulda README which shows how to install along side Rspec. It even says it provides "Test::Unit- and RSpec-compatible one-liners that test common Rails functionality. These tests would otherwise be much longer, more complex, and error-prone."

    Edit (examples):

    At the top of my specs, I always declare my Class relationship and validation tests which are concise and easy to read.

    describe Component do
    
      context 'relationships' do
        it { should belong_to(:technology)}
        it { should have_many(:system_components) }
        it { should have_and_belong_to_many(:variables) }
        it { should have_many(:images).dependent(:destroy) }
        it { should have_many(:documents).dependent(:destroy) }
      end
    
      context 'validations' do
        it { should validate_presence_of(:make) }
        it { should validate_presence_of(:model) }
        it { should ensure_length_of(:name).is_at_most(100) }
        it { should validate_presence_of(:technology_id) }
      end
    end
    

    Then the rest of my spec will have more complex tests where I am using mocks and stubs which come from Rspec.