Steve Klabnik was asking about RSpec’s implicit subject feature earlier today on Twitter:
rspec users: implicit subject, yes or no? I have my opinion, curious what yours is.
— Steve Klabnik (@steveklabnik) January 17, 2014
In a chorus of nopes, I was one of the few maybe-sometimeses, and that got me thinking about why I almost like it so much.
A Ruby port of robotfindskitten that I’ve been working on contains the following couple of tests of its random item tumbler for selecting random items to place on the map:
context "when you pick two items" do
subject { itemble.pick(2) }
it { should include("One item.") }
it { should include("Another item.") }
end
context "when you pick just one item" do
subject { itemble.pick(1) }
it { should have(1).item }
end
This is fantastic! In essence, each context
block covers a different
“when” situation, and every important consequence gets its own separately
executed test. So it’s as terse as if I’d just written two tests, but it
gives me more fine-grained feedback. But look at my third test:
context "when you run it several times in a row" do
it "should not always return things in the same order" do
results = []
100.times { results << itemble.pick(1) }
results.sort.uniq.should have(2).different_results
end
end
As soon as I’m doing something more interesting, I have to switch back to a more traditional style of test, and it means there’s suddenly a glaring inconsistency in how my tests are written. And so, in practice, I rarely end up using implicit subject in real life.
(HA! I bet you thought I wasn’t going to get a post up tonight!)