Search code examples
ruby-on-railsrubyrspecrspec-rails

rspec expect redirect_to fail


Sometimes new (very DRY) rspec syntax makes me crazy...

Rspec v 2.14.1

describe "POST create" do
  subject { post :create, contractor: valid_params }

  context "by user" do
    before { sign_in @legal.user }

    it "contractor successful created" do
      expect { subject }.to redirect_to(contractor_path(assigns(:contractor).id))

I have error & question here:

 NoMethodError: # :contractor variable not defined
   undefined method `id' for nil:NilClass

It seems that expect take an operator before controller method post executes, because I try to raise this method.

My code:

def create
  @contractor = Contractor.restrict!(current_accreditation).new(permitted_params) # TODO move to the IR::Base
  if @contractor.save
    current_accreditation = @contractor.create_legal!(user: current_user) # TODO legal create
    redirect_to(@contractor)
  else
    render(:new)
  end
end

Secondly, why I have an error when try

expect(subject).to ...

Why {} works, but () no? In relish docs this method work great: https://www.relishapp.com/rspec/rspec-rails/docs/matchers/redirect-to-matcher


Solution

  • Kinda unrelated but I've found the following helpful:

    • Use expect {} when you want to test before/after of whatever's in the block. eg. expect { subject } to change(User, :count) - you want to check the count before, then after, to work out the difference and see if it actually changed.

    • Use expect () to verify the outcome of a block, eg. that a redirect occurred, or something got assigned, etc.

    Your test with the assigns(:contractor) doesn't work because you're using the {} notation - so it's trying to work out the assigns(:contractor).id both before and after evaluating the subject (and of course, before the subject, it doesn't exist).