27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Behavior-driven development<br />

A nice way to tidy this up is to move the call to Bacon.new into a subject block.<br />

subject calls allow you to create an object to reference in all specs inside the<br />

describe block, 6 declaring it the subject (both literally and figuratively) of all the tests<br />

inside the describe block. You can define a subject like this:<br />

subject { Bacon.new }<br />

In the context of the entire spec, it looks like the following listing.<br />

Listing 2.14 bacon/spec/bacon_spec.rb<br />

require 'bacon'<br />

describe Bacon do<br />

subject { Bacon.new }<br />

it "is edible" do<br />

Bacon.new.edible?.should be_true<br />

end<br />

it "expired!" do<br />

bacon = Bacon.new<br />

bacon.expired!<br />

bacon.expired.should be_true<br />

end<br />

end<br />

Now that you have the subject, you can cut a lot of the code out of the first spec and<br />

refine it:<br />

its(:edible?) { should be_true }<br />

First, the its method takes the name of a method to call on the subject of these tests.<br />

The block specified should contain an assertion for the output of that method. Unlike<br />

before, you’re not calling should on an object, as you have done in previous tests, but<br />

rather on seemingly nothing at all. If you do this, RSpec figures out that you mean the<br />

subject you defined, so it calls should on that.<br />

You can also reference the subject manually in your tests, as you’ll see when you<br />

write the expired! example shown in the following listing.<br />

Listing 2.15 bacon/spec/bacon_spec.rb<br />

it "expired!" do<br />

subject.expired!<br />

subject.should_not be_edible<br />

end<br />

Here, the expired! method must be called on the subject because it is only defined<br />

on your Bacon class. For readability’s sake, you explicitly call the should_not method<br />

on the subject and specify that edible? should return false.<br />

6 Or inside a context block, which we use later. It works in a similar way to the describe blocks.<br />

33

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!