RSpec, implicit subject and exceptions

Is there a way to properly test the collection of exceptions with implicit subjects in rspec?

For example, this fails:

describe 'test' do subject {raise 'an exception'} it {should raise_exception} end 

But this goes:

 describe 'test' do it "should raise an exception" do lambda{raise 'an exception'}.should raise_exception end end 

Why is this?

+4
source share
2 answers

subject takes a block that returns a remainder object.

What you want is:

 describe 'test' do subject { lambda { raise 'an exception' } } it { should raise_exception } end 

Edit: comment explanation

It:

 describe 'test' do subject { foo } it { should blah_blah_blah } end 

more or less equivalent

 (foo).should blah_blah_blah 

Now consider: without lambda this will become:

 (raise 'an exception').should raise_exception 

See here that an exception occurs when an object is evaluated (before it should called at all). While with lambda it becomes:

 lambda { raise 'an exception' }.should raise_exception 

Here, the subject is the lambda, which is evaluated only when the should call is evaluated (in the context where the exception will be caught).

While the “subject” is re-evaluated each time, it should still evaluate what you want to be called should .

+7
source

Another answer explains the solution pretty well. I just wanted to mention that RSpec has a special assistant called expect . This is a little easier to read:

 # instead of saying: lambda { raise 'exception' }.should raise_exception # you can say: expect { raise 'exception' }.to raise_error # a few more examples: expect { ... }.to raise_error expect { ... }.to raise_error(ErrorClass) expect { ... }.to raise_error("message") expect { ... }.to raise_error(ErrorClass, "message") 

More information can be found in the RSpec documentation for embedded matches .

+1
source

All Articles