Search code examples
rubyunit-testingshoulda

Shoulda: How would I use an instance variable outside of a setup or should block?


I'm trying to do something like the following:

@special_attributes = Model.new.methods.select # a special subset
@special_attributes.each do |attribute|
  context "A model with #{attribute}" do
    setup do
      @model = Model.new
    end
    should "respond to it by name" do
      assert_respond_to @model, attribute
    end
  end
end

However, @special_attributes is out of scope when running the unit tests, leaving me with a nil object on line 2. I can't figure out where/how to define it to bring it in scope. Any thoughts?


Solution

  • Got it (I think). Shoulda is executing the block in the context of Shoulda::Context. In the above case, @special_attributes is an instance variable of my test class, not Shoulda::Context. To fix this, instead of using instance variables, just use local variables in the context block.

    So, for example:

    context "Model's" do
      model = Model.new
      special_attributes = model.methods.select # a special subset
      special_attributes.each do |attribute|
    
        context "attribute #{attribute}" do
          setup do
            @model = model
          end
          should "should have a special characteristic"
            assert_respond_to @model, attribute
            ...
          end
        end
    
      end
    end