rspec / rspec-core

RSpec runner and formatters
http://rspec.info
MIT License
1.23k stars 765 forks source link

Raise errors if `it` executed in a `before` block #3038

Closed fmichaut-diff closed 1 year ago

fmichaut-diff commented 1 year ago

Subject of the issue

Currently, if a it block (example block) is defined inside a before block, the it block will never run.

Your environment

Steps to reproduce

[...]
      context 'some deeply nested context' do
        let(:deleted_list) { [] }

        before do
          expect(TestClass).to receive(:delete).exactly(60).times do |arg|
            deleted_list << arg.to_i
          end

          it 'only uses what was deleted' do
            expect do
              described_class.new(object).call
            end.to change(deleted_list, :size).by(+60)

            expect(deleted_list).to eq(ids_list)
          end
        end
      end
[...]

This will never run, because the end of the before is after the it block. (this is a mistake, and currently no errors are raised so the user believes it is working)

Expected behavior

This should raise an error, as much as using let in an it block is an error.

Actual behavior

The current behavior silently skips the it blocks, and the user might never realise the specs are never run.

JonRowe commented 1 year ago

:wave: You do get an error if the block is executed:

`it` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block).

But if you have no other specs the block is never executed, which is what happened in your case.