mewcrow
2014-06-18T19:17:23Z

1_intro_to_subject.rb

| # RSpec's subject method, both implicitly and explicitly set, is useful for
| # declaratively setting up the context of the object under test. If you provide a
| # class for your describe block, subject will implicitly be set to a new instance
| # of this class (with no arguments passed to the constructor). If you want
| # something more complex done, such as setting arguments, you can use the
| # explicit subject setter, which takes a block.
| describe Person do
| context "born 19 years ago" do
| subject { Person.new(:birthdate => 19.years.ago }
| it { should be_eligible_to_vote }
| its(:age) { should == 19 }
| it "should be younger than a 20 year old" do
| twenty_year_old = Person.new(:birthday => 20.years.ago)
| subject.should be_younger_than(twenty_year_old)
| end
| end
| end

2_delayed_execution_of_subject.rb

| # The subject block is called after any befores. In fact, it is not called until
| # it is referenced in the spec - the compact syntaxes of 'it { should }' and
| # 'its(:property)' implicitly call subject as needed*. This means any method
| # calls in the subject block reference the state of the #system (like your db),
| # at the time subject is called.
| describe "the oldest person" do
| subject { Person.new(:birthdate => Person.oldest_person.birthdate - 1) }
| it "should be older than the next oldest person" do
| original_oldest_person = Person.new(:birthdate => 100.years.ago)
| subject.should be_older_than(original_oldest_person)
| end
| end
|
| # *The latter syntax actual resets subject, the getter, to be the result of the
| # property access, allowing for the intriguing abuse of syntax: 'its(:property) {
| # subject.should....'

3_subjecting_a_class_method_itself.rb

| # subject thus provides a decent syntax for testing method calls directly.
| # Sometimes, though, you have methods you want to test almost purely based on
| # what is passed into them, with few other concerns of state, for instance, when
| # testing class methods. These specs may have a little shared set-up needed, but
| # really the true object under test is the method call itself. In these cases it
| # makes sense to set that as the subject, and this leads to an effective and
| # succinct, if slightly distasteful, pattern for setting the method arguments via
| # standard rspec ivar trickery.
| describe ".first" do
| before { Person.create_10_people }
| subject { Person.first(@number_of_people) }
| it "should return the specified number of people" do
| @number_of_people = 5
| subject.size.should == 5
| end
|
| it "should return a single person when so specified" do
| @number_of_people = 1
| subject.should be_a(Person)
| end
|
| it "should default to returning a single person" do
| subject.should be_a(Person)
| end
| end

4_using_a_lambda_for_brevity_and_directness.rb

| # I was bemoaning the difference between ruby and more functional languages like
| # JavaScript, where you do have ways of easily differentiating between a method
| # reference and call (parentheses), and how that would make a pattern like this
| # easier by letting you set the method as the subject and then call it in the
| # spec. Then I realized, of course ruby has a way for creating a callable
| # reference like this: a lambda.
| describe ".first" do
| subject { lambda { |number_of_people| Person.first(number_of_people ) } }
| it { subject.call(5).size.should == 5 }
| it { subject.call(1).should be_a(Person) }
| it { subject.call.should be_a(Person)
| end

5_in_conclusion.txt

| If I continue to like this pattern enough after more usage I'll probably see if I
| can get them to accept a patch to allow passing of arguments directly into
| subject itself. That could possibly get a little messy in the code for subject
| itself, but behind the scenes gymnastics to get a nice testing syntax is what
| rspec is all about, after all.