Differences between expect{} and expect() in Rspec

Yingqi Chen
The Startup
Published in
2 min readMay 19, 2020

--

With Rspec, we can test if a return value is what we “expect”, and also observe if something changes as we “expect”. And we can use expect to achieve both! The key is in: what is that you are passing to “expect”. expect{} will tell expect to observe the whole process while expect() will evaluate inside the () first and check if the return value matches the matchers following.

Here is a case where I met recently, I wanted to test the create request, so I wrote the following codes:

describe '#create' do  let(:params){    {:volunteer =>  {      :image_url=>"new.jpg",      :name=>"new",      :job_desc=>"new description"    }   }   }  let(:create_volunteer){post "/api/v1/volunteers", :params => params}...   it "creates one more volunteer" do      ...#what does it mean to have one more volunteer?   endend

So you can see that, at first, I assign a hash called volunteer to params variable, and then assign a request to create_volunteer. So when create_volunteer is called, post “/api/v1/volunteers”,request is fired and params will be passed to the request.

To check if we create an object successfully, there are two ways. The first one is to check the total amount of objects in the database, the second one is directly checking for the changes.

Because what is changed during an example stays in an example, so to begin with, if I don’t set up anything, within this example, the amounts of volunteer objects will be 0. Therefore, I will call create_volunteer method and after that, volunteer instances amount will increase to 1.

My first solution would be, notice that because we only want to check for the return value of Volunteer.count, so I use parenthesis after expect.

it "creates one more volunteer" do  create_volunteer  expect(Volunteer.count).to eq(1)end

To check for the changes, however, I use this second solution:

it "creates one more volunteer" do  expect{create_volunteer}.to change(Volunteer, :count).by(1)end

Notice how I use {} after expect ? That means I am passing a code block to expect , it actually equals this:

expect do    create_volunteerend.to change(Volunteer, :count).by(1)

They are the same. Basically they are all saying: Hey expect, I am going to change Volunteer.count after create_volunteer , I need you to pay attention to Volunteer.count and tell me if it changes by 1.

Now it should be clear that when checking if changes happen as I want, you should use {} or do end block(they are the same), while if just checking a return value, should use ().

Thanks for reading!

--

--

Yingqi Chen
The Startup

Software engineer and a blockchain noob. Excited about the new world!!LinkedIn:https://www.linkedin.com/in/yingqi-chen/