rspec-core: Inherit and extend let definitions in inner describe blocks.
I’ve taken to an idiom like the following:
describe Post do
subject { Post.new(post_attributes) }
let(:post_attributes) { { } }
its(:description) { should be_empty }
describe "with a title" do
let(:post_attributes) { { title: "10 things about yak shaving you're doing wrong" } }
its(:description) { should == "10 things about yak shaving you're doing wrong" }
describe "with an author" do
let(:post_attributes) { { title: "10 things about yak shaving you're doing wrong", author: "Ernest Holbrecht" } }
its(:description) { should == "10 things about yak shaving you're doing wrong by Ernest Holbrecht" }
end
end
end
The Post.new call is DRYed up into the top of the spec, and each nested describe block defined what’s different from its parent block. Except: here, the innermost describe block’s definition of post_attributes repeats the title from the one above it.
I’d prefer to say something like this:
context "with an author" do
let(:post_attributes) { super.merge( author: "Ernest Holbrecht" ) }
its(:description) { should == "10 things about yak shaving you're doing wrong by Ernest Holbrecht" }
end
Unfortunately, I don’t think we can use super, it would have to be super() (which is uglier) or else we’d get the error “Implicit argument passing of super from method defined by define_method() is not supported. Specify all arguments explicitly.”
So this issue is here to decide two things:
- Is this a good thing to add to RSpec?
- If so, what’s the right word to use to refer to the inherited value of a let?
I’m happy to write the implementation.
About this issue
- Original URL
- State: closed
- Created 13 years ago
- Comments: 26 (7 by maintainers)
TLDR;
Only found this neat feature so many years later ❤️
I stumbled into an error when using
superinstead ofsuper(), but It is nicely explained here: https://rspec.info/blog/2013/02/rspec-2-13-is-released/#let-and-subject-declarations-can-use-superNice. I found this topic in 2019. 👍 Still working for RSpec 3.8.
Actually it does not make sense for LetOverride to perform the super.tap. I think the least surprising, and more flexible solution is to to just perform super instead.
Which allows:
I was thinking about the same feature but in subject method… and what do you think about extra argument for block, something like:
You could avoid method name problems this way 😉