RSpec 3 syntax is more verbose.
About twice as many characters to type to stub something:
obj.stub(client: client) # old
allow(obj).to receive(:client).and_return(client) # new
allow(obj).to receive(client: client) # possible? still much longer
allow(obj, client: client) # I might wrap it in this
More characters to type for every single assertion (multiply by number of assertions desired):
obj.should == value
expect(obj).to eq value # +4 characters
obj.should_receive(:method)
expect(obj).to receive(:method) # +4 characters
expect(obj, eq value) # +2 characters and doesn't read as well
# old frowned upon "its" extension, but look how few keystrokes, and how DRY
its(:body) { should include(text) }
# new (via transpec)
describe '#body' do
subject { super().body } # jon would disapprove of this anyway?
it { is_expected.to include(text) } # why is there one _ and one . (says my don't make me think brain)
end
its(:body) { is_expected.to include(text) }
I think there are more examples too.
But you know, I don't so much mind the extra typing, it's probably having to type (
that bugs me. That character is significantly harder to type than .
and ==
.
Was the less metaprogramming, less magical solution worth it?
I have no easy solution to this by the way. Just trying to communicate something I expressed in 140 characters better.
Firstly, thank you for such a thorough response! I know you're busy. I really appreciate it. Respect+++.
The lack of DRYness of which I speak is between the specdoc and the test body.
The word
body
is included twice. The concept is included twice (subject.body and 'the body'). Compare it to:This example is tiny and contrived but consider a more fully featured example and count the number of times the method under test is repeated either in the test body or in the specdoc. Imagine it is a long method name. I complain in more detail here: https://github.com/rails-oceania/rspec-subject_call/blob/master/README.md#the-situation
The same situation happens with contexts if you use them to describe specific cases rather than generalised assertions.
I'm not sure which of these two flavours you think is better. I'm not sure which is better, to be honest. But I have noticed that sometimes my contexts and the first line inside of their blocks sometimes feel very un-DRY. This is not related to RSpec 3 versus RSpec 2 syntax, though.
Yes I know. It will probably just take a little getting used to. Are any of these better (or worse? :P) ?
You're right. And now that I think more about it, this is a tremendous boon to making RSpec easier to learn.
I would like to figure out ways to incrementally get out of the business of writing code for tests and get more into the business of using a Ruby DSL to specify what I expect. In my mind, that means moving away from test names with test bodies that sort of resemble OOP methods and towards more declarative syntax with procedural-based fallback options for tricky tests. I believe this kind of approach would make RSpec much more succinct. I'm yet to figure out what the declarative syntax would actually be, though. ;-)