[RSpec] problems with a rails controller spec using AASM


#1

Hi All,

I’m trying to spec out a Rails controller and I’m coming up with a bit
of a problem. I’m pretty sure it’s something fairly simple but I can
no longer see the wood for the trees.

I have a Jobs controller that looks like this (this is just the action
with the problem for brevity)

class JobsController < ApplicationController
before_filter :require_user

def accept
@job = Job.find_by_jobno(params[:id])
unless @job.accepted?
@job.accept!
add_message “Job accepted”
else
add_message “Job already accepted”
end
redirect_to(job_path(@job.jobno))
end
end

And here’s the relevant part of the specs:

describe “when accessed through a browser” do
before(:each) do
@claim = Claim.make()
@inspector = Inspector.make(:inspector)
@job = Job.make(:jobno => 1)

controller.stub!(:current_user).and_return(@inspector)
controller.stub!(:login_required).and_return(true)

end

describe “when accepting a job” do

it "should find the job" do
  Job.should_receive(:find_by_jobno).with("1").and_return(@job)
  do_accept
end

it "should redirect to the job page" do
  do_accept
  response.should redirect_to(job_path(@job.foxpro_jobno))
end

describe "if it's already accepted" do
  before(:each) do
    @job.status = "accepted"
    @job.save
  end

  it "should add a flash message" do
    do_accept
    flash[:message].should == "Job already accepted"
  end

  it "should not change the job status" do
    do_accept
    @job.status.should == "accepted"
  end
end

describe "if it has yet to be accepted" do

  it "should accept the job" do
    @job.should_receive(:accept!)
    do_accept
  end

  it "should add a flash message" do
    do_accept
    flash[:message].should == "Job accepted"
  end

  it "should change the status" do
    do_accept
    @job.status.should == "accepted"
  end
end

def do_accept
  get_with @inspector, :accept, :id => 1
end

end
end

Some info: RSpec 1.2.6. It’s a restful controller with the accept
method being an additional member. I’m using Machinist to create the
objects in the database and I’m using Rubyist’s AASM for state
changes. The default state for a new Job is “unaccepted”.

When I run the code through the browser it all works as I would expect
but when I run the specs I get the following failures, all other specs
pass:

Spec::Mocks::MockExpectationError in ‘JobsController when accessed
through a browser when accepting a job if it has yet to be accepted
should accept the job’
#Job:0x398a988 expected :accept! with (any args) once, but received it
0 times

And

‘JobsController when accessed through a browser when accepting a job
if it has yet to be accepted should change the status’ FAILED
expected: “accepted”,
got: “unaccepted” (using ==)

Any help would be much appreciated.

Thanks,

Andy


#2

Hi Matt,

You’re a star! That was exactly it. I guess I should start pair
programming :slight_smile:

Thanks

2009/5/12 Matt W. removed_email_address@domain.invalid:


#3

On 12 May 2009, at 17:59, Andy Henson wrote:

Job.find_by_jobno(

needs to be stubbed all the time to return your job, or at least in
the examples that are failing.

Matt W.
http://blog.mattwynne.net
http://www.songkick.com