Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I `expect` something which raises exception in RSpec?

I have a method which performs some actions on Cat model and in case of incorrect input raises an exception:

context "hungry cat" do   it { expect { eat(what: nil) }.to raise_error }  end 

What I want to do is to check whether this method change cats status, like that:

context "hungry cat" do   it { expect { eat(what: nil) }.to raise_error }    it { expect { eat(what: nil) }.not_to change(cat, :status) }  end 

The problem is that since eat(what: nil) will raise an exception the second it will fail no matter what. So, is it possible to ignore exception and check some condition?

I know that it's possible to do something like:

it do    expect do     begin       eat(what: nil)     rescue     end   end.not_to change(cat, :status) end 

But it's way too ugly.

like image 601
Andrew Avatar asked May 31 '13 13:05

Andrew


People also ask

What is expect in RSpec?

rspec-expectations ships with a number of built-in matchers. Each matcher can be used. with expect(..). to or expect(..). not_to to define positive and negative expectations.

How do you raise errors in Ruby?

Ruby actually gives you the power to manually raise exceptions yourself by calling Kernel#raise. This allows you to choose what type of exception to raise and even set your own error message. If you do not specify what type of exception to raise, Ruby will default to RuntimeError (a subclass of StandardError ).

What is subject in RSpec?

Summary: RSpec's subject is a special variable that refers to the object being tested. Expectations can be set on it implicitly, which supports one-line examples. It is clear to the reader in some idiomatic cases, but is otherwise hard to understand and should be avoided.


1 Answers

You can chain positive assertions with and. If you want to mix in a negated one in the chain, RSpec 3.1 introduced define_negated_matcher.

You could do something like:

RSpec::Matchers.define_negated_matcher :avoid_changing, :change  expect { eat(what: nil) }   .to raise_error   .and avoid_changing(cat, :status) 

Inspired by this comment.

like image 157
Jan Klimo Avatar answered Sep 23 '22 08:09

Jan Klimo