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:

[code]   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 [/code]

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:

[code] 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

[/code]

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?

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: