How to override setup values, like RSpec `let`, in shoulda contexts?

ruby, shoulda

Solution

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

Problem

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.

Original source