LeakyBucket
LeakyBucket

Reputation: 160

ID problems with Mongoid and RSpec

So, I've been beating my head against this for a while and just can't make any progress.

I have the following controller action:

def create
  @job = Job.new(params[:job])

  respond_to do |format|
    if @job.save
      flash[:notice] = "The Job is ready to be configured"
      format.html { redirect_to setup_job_path(@job.id) }
      format.json { head :ok }
    else
      format.html { redirect_to new_job_path, notice: 'There was an error creating the job.' }
      format.json { render json: @job.errors, status: :unprocessable_entity }
    end
  end
end

I am trying to test this action. Here is my test for the redirect on successful creation.

it "redirects to the Job setup" do
    job.stub(:id=).with(BSON::ObjectId.new).and_return(job)
    job.stub(:save)
    post :create
    response.should redirect_to(setup_job_path(job.id))
end

job is defined for the whole suite here:

let (:job) { mock_model(Job).as_null_object }

I keep getting the following error:

2) JobsController POST create when the job saves successfully redirects to the Job setup
 Failure/Error: response.should redirect_to(setup_job_path(job.id))
   Expected response to be a redirect to <http://test.host/jobs/1005/setup> but was a redirect to <http://test.host/jobs/4ea58505d7beba436f000006/setup>

I've tried a few different things but no matter what I try I can't seem to get the proper object ID in my test.

Upvotes: 1

Views: 467

Answers (1)

Simone Carletti
Simone Carletti

Reputation: 176412

If you stub the :id= you are creating a very weak test. In fact, unless you are super-confident about the Mongoid internals, chances are your tests will break if Mongoid changes the way it generates id. And in fact, it doesn't work.

Also, keep in mind you create a job variable, but you are not passing this variable inside the controller. It means, the :create action will initialize its own job instance at

@job = Job.new(params[:job])

and it will completely ignore your job.

I suggest you to use assigns.

it "redirects to the Job setup" do
  post :create
  response.should redirect_to(setup_job_path(assigns(:job)))
end

Upvotes: 1

Related Questions