Rspec and Shoulda - complementary or alternatives?
Asked Answered
M

2

8

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?

Moneymaking answered 5/1, 2011 at 21:46 Comment(0)
B
13

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.

Brendin answered 6/1, 2011 at 1:35 Comment(6)
Here are some more perspectives on it: https://mcmap.net/q/800936/-rspec-vs-shouldaBrendin
I'd love some examples of things you do with the combo that couldn't be done with one or the other. If there are ways I can clean up my tests, I am all for it. I was using shoulda + matchy together, then found that rspec basically did that and went from there. Is it just things like the controller matchers?Townsend
I updated my answer with some of the shoulda tests I have. One rule I tend to follow is that Shoulda is used for Rails' built in Class macros like validations and relationships, and Rspec is for more complex tests where mock objects and method stubbing is required.Brendin
+1 They're complimentary, at least when used with Rails. Lets you do things like it { should validate_presence_of(...) }.Haematoxylin
+1 @Beerlington, can I ask whether in your model test files you also tend to have some kind of context 'database schema' where you would use shoulda methods like have_db_column and have_db_index? Or is this considered too excessive, unnecessary and/or low-level to put in a model test file?Odometer
@PaulFioravanti I don't test for those. I only test things that are related to behavior and I don't consider the presence of a column or an index behavior. Database columns don't just disappear unless someone intentionally removes them, but you can protect against that with code reviews and trust :)Brendin
T
0

rspec and shoulda are alternatives to each other. I started with shoulda, as well, and moving to rspec is as simple as s/context/describe/, s/should/it/, and you're off to the races. rspec has a bunch of tricks, various integrations, and more complex matchers, so I'm using it more these days myself.

One of my initial frustrations was that it was nearly impossible to find a tutorial that didn't assume Rails and Cucumber. Don't overthink it - there's a lot you can do with it, but you don't have to have a monster of a solution in place before you can use it.

Townsend answered 5/1, 2011 at 21:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.