Can't get this Rspec test to pass

Hello,
I’m completely new to Rspec testing and I’m finding it very difficult
to
mock specific objects.

In this test, I have a before block setup as such:

  before do
    setup_controller_for_warden
    controller.session[:operation_id] = 1
    @operator = Factory :operator
    sign_in :operator, @operator

    @persist_herd = Herd.new
    @persist_herd.operation_id = 1;
    @persist_herd.herd_name = 'Persisted Herd
(herd_rations_controller_spec)'
    @persist_herd.save!
  end

  describe "GET new" do
    it "assigns a new herd_ration as @herd_ration" do
      HerdRation.stub(:new){ mock_herd_ration }
      Herd.stub(:find).with(1) { @persistant_herd }

      get :new, :herd_id => 1
      assigns(:herd_ration).should be(mock_herd_ration)
      response.should be_success
    end
  end


and here's my controller method:

  def new
    @herd_ration = HerdRation.new
    @herd = Herd.find(params[:herd_id])

    if @herd
      respond_with(@herd_rations, :layout=> !request.xhr?)
    else
      redirect_to(root_url, :notice => 'No herd selected for ration.')
    end
  end

Here’s the catch - we have this groovy little plugin that globally
enforces
a model scope via a session id, in this case: session[:operation_id].

Here’s the code for the plugin:

module ApplicationScopeManager


   mattr_accessor :global_scope
   @@global_scope = []

   mattr_accessor :local_scope
   @@local_scope = {}

   def self.included(base)
      base.send :extend, ClassMethods
   end

   def self.setup
      yield self
   end

   module ClassMethods


      def method_missing(name, *args, &block)

         return acts_as_scope_manager($1, args) if name.to_s =~
/^acts_as_scope_manager_for_(.*)/

         return honors_scope_of($1, args) if name.to_s =~
/^honors_scope_of_(.*)/

         return current_scope_for($1) if name.to_s =~
/^current_scope_for_(.*)/

         super
      end

      def current_scope_for(scope)
         Thread.current[scope.to_sym]
      end

      def acts_as_scope_manager(scope, *args)
         options = args[0].extract_options! if args
         send :include, InstanceMethods

         set_global_scope(scope,options[:with_global_scope]) if
options[:with_global_scope]

         send :before_filter, "set_scope_for_#{scope}".to_sym if
self.ancestors.include? ActionController::Base
         send :default_scope, where(scope.to_sym =>
send("current_scope_for_#{scope}".to_sym)[:finder_scope]).create_with(scope.to_sym
=>
         send("current_scope_for_#{scope}".to_sym)[:creator_scope]) if
(self.ancestors.include? ActiveRecord::Base) && 
Thread.current[scope.to_sym]
      end

      alias honors_scope_of acts_as_scope_manager

      private


      def set_global_scope(scope, *args)
         Thread.current[scope.to_sym] = {:global_scope => args}
      end

   end

   module InstanceMethods

      def method_missing(name, *args, &block)

         return set_scope_for($1, args) if name.to_s =~
/^set_scope_for_(.*)/

         super
      end

      private

      def set_scope_for(scope, *args)
         if session[scope].class == Array
            application_scope = {:finder_scope => session[scope],
:creator_scope => nil }
         else
            application_scope = {:finder_scope => [session[scope]],
:creator_scope => session[scope] }
         end

         application_scope[:finder_scope] = 
application_scope[:finder_scope]
+ Thread.current[scope.to_sym][:global_scope] if
Thread.current[scope.to_sym][:global_scope]

         Thread.current[scope.to_sym] = application_scope

      end

   end
end

This plugin enforces any model that calls the
honors_scope_of_operation_id
to include a lookup of the session[:operation_id] in all database calls.
For instance if I do a Model.find(params[:id]) it will automatically
add a
WHERE “field_name”.“operation_id” = to the where clause. The problem
I’m
having is that I can’t seem to mock the session[:operation_id] in my
Rspec
tests. I thought setting it this way
controller.session[:operation_id] =
1 in the before block would have been sufficient.

Any ideas?

View this message in context:
http://old.nabble.com/Can't-get-this-Rspec-test-to-pass-tp32037786p32037786.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.

Hello, I found a solution that makes this test pass and it was simply to
mock
out the controller’s find method as such:

Herd.stub(:find).with(@persist_herd.id) { mock_herd }

I am probably not fully understanding RSpec but this feels strange to
me.
In my understanding of writing tests, you want to first prepare the test
environment by creating the proper database/objects relevant to the
testing
environment, pass the relevant parameters and test the results of method
you
are testing. Mocking out this controller code @herd =
Herd.find(params[:herd_id]) with this
Herd.stub(:find).with(@persist_herd.id) { mock_herd } doesn’t seem to
let
the controller test it’s own code? Why can’t the parameters I’m passing
to
the controller be enough to test Herd.find(params[:herd_id]) ?

Please help me understand this?

clem_c_rock wrote:

controller.session[:operation_id] = 1

describe “GET new” do

end

module ApplicationScopeManager
end
return acts_as_scope_manager($1, args) if name.to_s =~

  alias honors_scope_of acts_as_scope_manager

module InstanceMethods

application_scope[:finder_scope] +
[/code]
Any ideas?


View this message in context:
http://old.nabble.com/Can't-get-this-Rspec-test-to-pass-tp32037786p32061805.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.