Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference between 'expect' and 'should' in RSpec?

For example, these two tests:

it "fails to create given a bad player list" do
  Team.new("Random name", bad_players).should raise_error
end

and

it "fails to create given a bad player list" do
  expect {Team.new("Random name", bad_players)}.to raise_error
end

They return different outputs (the first one fails, while the 2nd one passes). I would expect both to either pass or fail depending on the contents of the Team model.

The full RSpec code is:

require_relative 'team'

describe "Team" do

  it "has a name" do
    Team.new("Random name").should respond_to(:name)
  end

  it "has a list of players" do
    Team.new("Random name").players.should be_kind_of Array
  end

  it "is favored if it has a celebrity on it"
  it "complains if there is a bad word in the name"

  context "given a bad list of players" do
    let(:bad_players) { {} }

    it "fails to create given a bad player list" do
      expect { Team.new("Random name", bad_players) }.to raise_error
    end
  end

end

The reason I thought 'should' would work is because of the similar syntax in the 'it "has a name"' test. If it turns out that 'should' is incorrect and 'expect...to' is correct, I would love to know when to use one vs. the other. Thanks.

like image 448
Richie Thomas Avatar asked Aug 06 '13 02:08

Richie Thomas


2 Answers

Quoting from https://github.com/rspec/rspec-expectations/blob/master/Should.md:

From the beginning RSpec::Expectations provided should and should_not methods to define expectations on any object. In version 2.11 expect method was introduced which is now the recommended way to define expectations on an object.

The next paragraph in that document describe the difference in implementation and why expect is now the recommended approach.

At this point, pretty much anything you can do with should and should_not can be done with expect. See http://rubydoc.info/gems/rspec-expectations/frames for details and expect usage.

As for your specific code, the reason the first example is failing is that the error is occurring before RSpec has a chance to get involved. You can still use should to check for the raising of an error, but you have to give RSpec a chance to work. The syntax is lambda {...}.should raise_error where ... is the code you're testing.

like image 100
Peter Alfvin Avatar answered Sep 20 '22 13:09

Peter Alfvin


aYes there is a difference

should will verify that what's on the rights side is true. It must be used for simple comparison of results.

(1+1).should eq(3-1)

expect takes a block and verify that the execution of the block has a specific effect. It must be use when comparing the situation before and after the block is executed

expect{ User.new.save }.to change(User, :count).by(1)

Use should as must as you can (it's easier to write) and expect only when should is not able to do the job

like image 29
Benj Avatar answered Sep 20 '22 13:09

Benj