[rspec-users] collection-based finder methods

amkirwan amkirwan at gmail.com
Wed Jul 22 10:12:46 EDT 2009

My spec is a messed up because I have tried everything I can think of
to mock but this is what I have for the show method. The @user
instance is setup in the login_and_before_filter_pass macros with the
following: @user = mock_model(Person, :null_object => true)

The error I keep receiving is that assigns[:letter].should equal
@letter keeps return that it is expecting a Person object instead of a
Letter object. The only way I can get it to pass is by putting
directly in the "should assign the found letter for the view"

I feel like I must be missing something about how stubbing and mocking

  # Get /admin/letters/1
  def show
    id = params[:id]
    @letter =  @user.letters.find(id)

describe Admin::LettersController, "SHOW GET /admin/letters/1" do

  before(:each) do

  def do_get
    put :show, {:id => "1"}, @session

  login_and_before_filter_pass(:filter => :admin_only,
                             :request_method => :get,
                             :action => :show,
                             :parameters => {:cas_user => 'ak730'})

  it "should be successful" do
    response.should be_success

  it "should find the letter requested" do

  it "should assign the found letter for the view" do
    # uncommenting will allow to pass
    # @user.letters.should_receive(:find).with("1").and_return
    assigns[:letter].should equal(@letter)

  it "should render show template" do
    response.should render_template("show")


On Jul 22, 9:13 am, David Chelimsky <dchelim... at gmail.com> wrote:
> On Tue, Jul 21, 2009 at 11:21 PM, amkirwan<amkir... at gmail.com> wrote:
> > How do I spec this following example from the Agile Rails Book listed
> > below. I am doing a similar thing in my controller and when I
> > attempted to change it to the collection way of doing the find I am
> > unable to get my spec to pass though I know it is working fine as my
> > cucumber features are passing
> > old rails way:
> > def show
> > @order = Order.find(params[:id])
> > end
> > new rails way collection-based:
> > def show
> > id = params[:id]
> > @order = @user.orders.find(id)
> This code is inherently untestable in an isolated/granular way. Your
> options are:
> * write higher level specs that use real data
>   * pros: simplicity and clarity in both code and specs
>   * cons: brittle due to runtime dependency on correct models, runs slow
> * write a very invasive spec with complex setup and instance_eval to
> set up the @user
>   * pros: runs fast, no runtime dependency on correct models
>   * cons: brittle due to dependency on internals, complex
> * refactor the code to make it easier to spec
>   * pros: more highly decoupled code, simpler specs, fast
>   * cons: more work up front, may disregard some of what Rails has to offer
> Note that the first two options are both brittle, but for different
> reasons. The first is brittle due to a runtime dependency. That means
> that when you run the spec the model has to be working correctly for
> the spec to pass, and a failure could be due to a problem in the model
> or in the controller.
> The second is due to a code dependency. That means that when you want
> to change this code, the spec will have to change as well. This is
> true of any case in which you use mocks or stubs to varying degrees,
> and that comes with its own tradeoffs. In this case, the necessary
> stubbing would be complex and invasive enough that it would be a
> concern to me.
> Getting to your original question - what does your spec look like now,
> and what failure message are you getting?
> Cheers,
> David
> > rescue
> > redirect_to :action => "index"
> > end
> > _______________________________________________
> > rspec-users mailing list
> > rspec-us... at rubyforge.org
> >http://rubyforge.org/mailman/listinfo/rspec-users
> _______________________________________________
> rspec-users mailing list
> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users

More information about the rspec-users mailing list