Is it possible to access the context object in rspec?

The following code does not work, but it is best to show what I am trying to achieve

context "this context describes the class" do

  subject do
    # described class is actually a module here
    c = Class.new.extend(described_class)
    c.some_method_that_has_been_added_through_extension
    c
  end

  # ... testing the class itself here ...

  context "instances of this class" do

    subject do
      # this doesn't work because it introduces a endless recursion bug
      # which makes perfectly sense
      subject.new
    end

  end

end

I also tried using a local variable in the inner context, which I initialized with the subject, but no luck. Is there any way to access the object of the external sphere from my definition of the object in the internal area?

+3
source share
3 answers

Something that obviously works is to use the instance variable in the internal context and instead initialize it not with subject, but subject.call. Subjects are Procs. Therefore, my first approach did not work.

context "instances of this class" do

  klass = subject.call
  subject { klass.new }

end
0
source

#subject . " " , , #its.

, , / , . , #subject #let : http://blog.davidchelimsky.net/blog/2012/05/13/spec-smell-explicit-use-of-subject/

let, https://www.relishapp.com/rspec/rspec-core/v/2-10/docs/helper-methods/let-and-let

, , .

context "this context describes the class" do
  let(:name_of_the_module) { Class.new.extend(described_class) }
  before do
    c.some_method_that_has_been_added_through_extension
  end

  # ... testing the class itself here ...

  context "instances of this class" do

    let(:better_name_that_describes_the_instance) { klass.new }

    # ... test the instance
  end

end

Sidenote , , . #let . YMMV

+3

, . , , , proc raise_error .

I found that you can give names subjects, for example lets. This will allow you to reference the named subjectfrom the outer scope in the new one subject. Here is an example:

describe 'do_some_math' do
  let!(:calculator) { create(:calculator) }

  # proc to be used with raise_error
  subject(:do_some_math) { 
    -> { calculator.do_some_math(with, complicated, args) } 
  }

  context 'when something breaks' do
    it { is_expected.to raise_error } # ok
  end

  context 'when everything works' do

    # here we call the named subject from the outer scope:
    subject { do_some_math.call } # nice and DRY

    it { is_expected.to be_a(Numeric) } # also ok!
  end
end
0
source

All Articles