rspec `its` syntax with dynamic conditions

brad picture brad · Oct 17, 2011 · Viewed 11.8k times · Source

I've been really loving using contexts, subjects and its with rspec to really clean up my test code. Typical example:

context "as a user" do
  subject{ Factory :user }

  its(:name){ should == "Bob" }
end

What I can't figure out though is how I could make this condition dynamic (ie. based on other objects). its appears to instance eval the attribute within the block so I lose access to everything around it. I'd love to do something like:

its(:name){ should == subject.contact.name }

But I can't see any way of achieving this. Does anyone know if there is some a method proxied through to this instance eval that gives access to the origin object? Or if there's any other way I can use methods outside the scope of the instance of the attribute that I'm checking?

additional info

It seems as if subject within the its block gets changed to the actual attribute (name in this case)

Interestingly, I have access to any of my let methods, but again, I don't have access to my original subject in question.

Answer

David picture David · Jan 27, 2012

You are almost answering yourself, use a let assignment before you set the subject. Then you can reference it everywhere:

context "as a user" do
  let(:user) { Factory(:user) }
  subject { user }
  its(:name) { should == user.contact.name }
end

I'm a context, subject, its lover too !