Robert Audi
Robert Audi

Reputation: 8467

RSpec: Why doesn't let work but before(:each) does?

I have the current spec:

describe "DELETE 'destroy'" do
  let(:client) { create(:client) }

  #before(:each) do
    #@client = create(:client)
  #end

  it "should delete a client" do
    expect {
      delete :destroy, :id => client
    }.to change(Client, :count).by(-1)
  end

  # ...

end

The example fails when I use let but works fine when I use before(:each).

Here is the implementation code:

def destroy
  client = Client.find(params[:id])
  if client.destroy
    flash[:success] = "Client deleted successfully"
    redirect_to kong_clients_url
  else
    flash[:error] = "Client not deleted for some reason"
    redirect_to kong_clients_url
  end
end

So why does the example fail when I use let?!

Upvotes: 2

Views: 970

Answers (1)

pjumble
pjumble

Reputation: 16960

let is lazy-evaluated, the record isn't created until you access the client property inside the expect/lambda (+1), but then it's immediately deleted (-1), so overall inside the expectation the count doesn't change.

You can use let! to force it to evaluate straight away:

let!(:client) { create(:client) }

Upvotes: 9

Related Questions