Skip to content

Tutorial: Simple Spec

jimweirich edited this page Sep 4, 2012 · 5 revisions

This is part of the RSpec/Given Tutorial

Let's start with a simple spec about character names.

Character Names

Feature: Create a Character

As a character I want to have a name so that I can be distinguished from other characters

  • can get and set Name

Getting the name.

I would reword that feature story into something like "Given a character with a name, we can get that name". Written in Given terminology we would get:

describe "Character has name" do
  Given(:guy) { Character.new("George") }
  Then { guy.name.should == "George" }
end

This is the simplest possible spec with a single Given clause and a single Then clause. The Given clause specifies what is assumed to be available for the test (in this case a character initialized with the name "George"). The Then clause specifies what must be true if the given assumptions are true, in this case, the character object will report his name.

Setting the name

But we didn't deal with setting the name. I would translate that part of the feature into the sentence "Given a character with a name, when I set the name, then I get the new name."

Let's add that to our existing spec:

describe "Character has name" do
  Given(:guy) { Character.new("George") }
  Then { guy.name.should == "George" }

  describe "changing the name" do
    When { guy.name = "Bill" }
    Then { guy.name.should == "Bill" }
  end
end

The nested describe block inherits the givens from the enclosing block. So it starts out with a character named "George". The When block specifies the code under test, in this case it is the name setter. The Then clause in the nested describe block specifies that asking for the name will now result in the new name.

Isolation and Clause Ordering

For each Then, the following clauses execute in order

  1. Any Given() or Given!(:var) blocks are run first, from the out describe/context blocks to the inner.
  2. All the When() and When(:var) blocks are run, from the outer to the inner scopes.
  3. The Given(:var) blocks are run upon demand, so the first reference to the variable in the Given(:var) block will cause that block to be evaluated. Given(:var) blocks are only evaluated once per Then clause.

Each Then clause is run independently, so Given and When clause will be re-run for each Then.

-- Next: Tutorial: Immediate Given