Here's a nice technique I use with RSpec that I would also like to use in projects that use Shoulda and Shoulda-context. But I don't know if it's possible. Is there a way to do this?
What I want: define a setup
(before
) block in an outer context that references a let
clause in a nested context. That way, inner contexts can configure values that are referenced in the outer setup
And the setup
can still be DRY across inner contexts.
RSpec example (this example is simple--please assume my real-life examples have a lot more code in the before
block that I don't want to duplicate):
describe Thing do
before do
# Notice that `user` isn't defined here--it's defined in `let` blocks
# in nested contexts below.
login_as user
# Assume there's lots more code here that I would like to keep
# DRY across contexts.
end
context "when logged in as an admin" do
# THIS IS THE MAGIC RIGHT HERE:
let(:user) { Factory(:user, role: "admin") }
it "should ..." ...
end
context "when logged in as a normal user" do
# THIS IS THE MAGIC RIGHT HERE:
let(:user) { Factory(:user) }
it "should ..." ...
end
end
To summarize: how can I do this with shoulda-context and Test::Unit?
Some things I have already tried that didn't work:
def
to redefine a method in each subcontext.before_should
in each subcontext.I've found helper methods inside the test class useful for pulling out code repeated between tests. Like this:
class MyTest < TestCase
context "when logged in as an admin" do
setup do
do_login Factory(:user, role: "admin")
end
should "..." do
...@user...
end
end
context "when logged in as an admin" do
setup do
do_login Factory(:user)
end
should "..." do
...@user...
end
end
def do_login(user)
login_as user
@user = user
# lots more setup code here...
end
end