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?
--
View this message in context:
http://old.nabble.com/Can%27t-get-this-Rspec-test-to-pass-tp32037786p32037786.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.
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?
--
Posted via http://www.ruby-forum.com/.
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.
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:>
> 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?
>
--
View this message in context:
http://old.nabble.com/Can%27t-get-this-Rspec-test-to-pass-tp32037786p32061805.html
Sent from the RubyOnRails Users mailing list archive at Nabble.com.
--
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.